package com.h3c.nem.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eos.common.constant.StatusCodeEnum;
import com.eos.common.custom.BusinessException;
import com.eos.common.util.IdWorker;
import com.eos.common.util.Result;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.h3c.nem.async.AsyncSendMessage;
import com.h3c.nem.async.AsyncSyncDataToHRSS;
import com.h3c.nem.bo.ElectronicSignBO;
import com.h3c.nem.bo.TbOfferWorkerBO;
import com.h3c.nem.cache.TbOfferWorkerCache;
import com.h3c.nem.client.AbilityClient;
import com.h3c.nem.config.SpringUtil;
import com.h3c.nem.config.mq.consumer.EmailAckReceiver;
import com.h3c.nem.config.mq.consumer.EsignAckReceiver;
import com.h3c.nem.config.properties.EmailSendProperties;
import com.h3c.nem.config.properties.TbOfferWorkerProperties;
import com.h3c.nem.dto.*;
import com.h3c.nem.dto.beisen.BeiSenBuildDTO;
import com.h3c.nem.dto.beisen.OcrDTO;
import com.h3c.nem.dto.beisen.OfferWorker;
import com.h3c.nem.dto.sap.SubmitFormalWorkerIdDTO;
import com.h3c.nem.entity.*;
import com.h3c.nem.enums.*;
import com.h3c.nem.mapper.TbOfferStudyMapper;
import com.h3c.nem.mapper.TbOfferWorkerMapper;
import com.h3c.nem.mapper.TbSchoolMapper;
import com.h3c.nem.mapper.TbWorkerExperienceMapper;
import com.h3c.nem.mapstruct.TbOfferWorkerMapstruct;
import com.h3c.nem.sap.RfcManager;
import com.h3c.nem.service.*;
import com.h3c.nem.utils.*;
import com.h3c.nem.vo.*;
import com.sap.conn.jco.*;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 预备员工基本信息实现类
 *
 * @author chenyifan
 * @since 2022-06-02 14:19:48
 */
@Service
@Slf4j
public class TbOfferWorkerServiceImpl extends ServiceImpl<TbOfferWorkerMapper, TbOfferWorker> implements ITbOfferWorkerService {

    @Resource
    private ITbApprovalRecordService approvalRecordService;

    @Resource
    private ITbPersonnelRegisterMiddleService personnelRegisterMiddleService;

    @Resource
    private ITbOfferAttachmentService attachmentService;

    @Resource
    private ITbOfferFamilyService familyService;

    @Resource
    private ITbOfferStudyService studyService;

    @Resource
    private ITbWorkerExperienceService iTbWorkerExperienceService;
    @Resource
    private ITbOfferLanguageService iTbOfferLanguageService;
    @Resource
    private ITbWorkerExperienceService workerExperienceService;
    @Resource
    private ITbOfferPatentService iTbOfferPatentService;
    @Resource
    private ITbOfferModifyService iTbOfferModifyService;
    @Resource
    private ITbOfferArchieveService iTbOfferArchieveService;
    @Resource
    private ISdTodoTaskService iSdTodoTaskService;
    @Resource
    private ISdNoticeRecordService iSdNoticeRecordService;
    @Resource
    private ISdDeptService iSdDeptService;
    @Resource
    private TbSchoolMapper tbSchoolMapper;
    @Resource
    private AsyncSendMessage asyncSendMessage;
    @Resource
    private CommService commService;
    @Resource
    private TbWorkerExperienceMapper tbWorkerExperienceMapper;
    @Resource
    private ITbOfferContactorService contactorService;
    @Resource
    private ISdAllWorkerService iSdAllWorkerService;
    @Resource
    private ISdEmailTemplateService emailTemplateService;
    @Resource
    private ITbOfferWorkerService iTbOfferWorkerService;
    @Resource
    private BeiSenService beiSenService;
    @Resource
    AsyncSyncDataToHRSS asyncSyncDataToHRSS;
    @Resource
    private SdRequestRecordService sdRequestRecordService;

    @Resource
    private TbOfferStudyMapper tbOfferStudyMapper;
    @Resource
    private TbOfferWorkerProperties offerWorkerProperties;
    @Resource
    private EmailSendProperties emailSendProperties;
    @Resource
    private ITbWorkerService iTbWorkerService;
    @Resource
    private ThreadPoolService threadPoolService;
    @Resource
    private TbOfferWorkerMapper tbOfferWorkerMapper;
    @Resource
    private AbilityClient abilityClient;
    @Resource
    private RfcManager rfcManager;

    @Value("${admp.url}")
    private String admpUrl;

    @Value("${prefix.downloadPath}")
    private String downloadPath;

    @Value("${ptability.token}")
    private String ptToken;

    @Value("${hrss.nem.account}")
    private String appId;

    @Value("${hrss.nem.password}")
    private String curSecret;

    @Value("${new.employee.feedback}")
    private String feedbackMail;

    private final SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyyMMdd");

    @Override
    public TbOfferWorker getOneByPhoneNo(String phoneNum) {
        return getOne(new QueryWrapper<TbOfferWorker>().lambda()
                .eq(TbOfferWorker::getPhoneNo, phoneNum)
                .notIn(TbOfferWorker::getWorkerStatus, Arrays.asList(
                        OfferWorkerStatusEnum.offer审批中,
                        OfferWorkerStatusEnum.已入职,
                        OfferWorkerStatusEnum.取消入职,
                        OfferWorkerStatusEnum.放弃入职))
        );
    }

    @Override
    public TbOfferWorker getOneByCertNo(String certNo) {
        TbOfferWorker one = getOne(new QueryWrapper<TbOfferWorker>().lambda()
                .eq(TbOfferWorker::getCertNo, certNo)
                .notIn(TbOfferWorker::getWorkerStatus, Arrays.asList(
                        OfferWorkerStatusEnum.offer审批中,
                        OfferWorkerStatusEnum.取消入职,
                        OfferWorkerStatusEnum.已入职,
                        OfferWorkerStatusEnum.放弃入职))
                .orderByDesc(TbOfferWorker::getWorkerId)
                .last("limit 1")
        );
        //工卡照片被驳回时可再次登录重新上传
        if (one == null) {
            TbOfferWorker worker = getOne(new QueryWrapper<TbOfferWorker>().lambda()
                    .eq(TbOfferWorker::getCertNo, certNo)
                    .notIn(TbOfferWorker::getWorkerStatus, Arrays.asList(
                            OfferWorkerStatusEnum.offer审批中,
                            OfferWorkerStatusEnum.取消入职,
                            OfferWorkerStatusEnum.放弃入职))
                    .orderByDesc(TbOfferWorker::getWorkerId)
                    .last("limit 1")
            );
            if (worker != null) {
                List<TbOfferAttachment> cardPic = attachmentService.lambdaQuery().eq(TbOfferAttachment::getWorkerId, worker.getWorkerId())
                        .eq(TbOfferAttachment::getFileType, 3)
                        .eq(TbOfferAttachment::getApprovalStatus, 3).list();
                if (!CollectionUtils.isEmpty(cardPic)) {
                    return worker;
                }
            }
        }
        return one;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveBasicInfo(TbOfferWorkerDTO workerDTO) {
        TbOfferWorker offerWorker = TbOfferWorkerMapstruct.INSTANCE.dto2Entity(workerDTO);

        offerWorker
                .setFirstPinyin(offerWorker.getFirstPinyin().replaceAll(" ", ""))
                .setLastPinyin(offerWorker.getLastPinyin().replaceAll(" ", ""))
                .setNamePinyin(offerWorker.getFirstPinyin().concat(offerWorker.getLastPinyin()))
                .setWorkerId(CommonUtil.getActivUser()
                        .getUserId()).setUpdateTime(new Date())
                .setAlreadySave(true)
                .setUpdatorInfo(CommonUtil.getActivUser().getUserId());
        updateById(offerWorker);
        TbOfferWorkerCache.updateFillStatus(CommonUtil.getActivUser().getUserId(), TbOfferWorkerCache.BASIC_INFO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateEntryDate(String workerId, UpdateEntryDateDTO updateEntryDateDTO) {
        TbOfferWorker offerWorker = getById(workerId);
        if(Objects.nonNull(offerWorker.getApplyReportDate())){
            throw new AppBusinessException("您之前提交的入职日期变更申请还在审核中，请耐心等待。");
        }
        if (offerWorker.getWorkerStatus().getCode() > OfferWorkerStatusEnum.待审核入职资料.getCode()) {
            throw new AppBusinessException("您的资料已通过审核，若仍需变更计划入职日期，请联系您的接口人");
        }
        update(null, new LambdaUpdateWrapper<TbOfferWorker>()
                .set(TbOfferWorker::getApplyReportDate, updateEntryDateDTO.getApplyDate())
                .set(TbOfferWorker::getApplyChangeReason, updateEntryDateDTO.getReason())
                .eq(TbOfferWorker::getWorkerId, workerId)
        );

        approvalRecordService.saveRecord(null,
                TbApprovalRecord.RESERVE_STAFF_MODIFIED,
                offerWorker.getWorkerId(),
                offerWorker.getWorkerId() + "/" + offerWorker.getWorkerName(),
                "您提交了修改入职日期申请,申请将入职日期从" + DateUtil.format(offerWorker.getPlanReportDate(), "yyyy-MM-dd") + "修改为" +
                        DateUtil.format(updateEntryDateDTO.getApplyDate(), "yyyy-MM-dd") + "修改原因：" + updateEntryDateDTO.getReason() + ",请等待管理员审批");
        HashMap<String, String> param = new HashMap<>(3);
        param.put("workerNameAndId", offerWorker.getWorkerName() + "/" + offerWorker.getWorkerId());
        param.put("oldDate", DateUtil.format(offerWorker.getPlanReportDate(), "yyyy-MM-dd"));
        param.put("newDate", DateUtil.format(updateEntryDateDTO.getApplyDate(), "yyyy-MM-dd"));
        ThreadUtil.execute(() -> {
            String receiveEmail = EmailUtil.getReceiveEmail(offerWorker.getWorkerId(), true, true, false, false);
            EmailUtil.sendPtEmail(emailSendProperties.getChangeInDateTemplateCode(), param, receiveEmail, "预备员工提交修改入职日期申请", null, null);
        });
    }

    @Override
    public TbOfferWorkerVO showBasicInfo() {
        TbOfferWorker offerWorker = getOne(new QueryWrapper<TbOfferWorker>().lambda()
                .eq(TbOfferWorker::getWorkerId, CommonUtil.getActivUser().getUserId())
        );
        log.info("birthday ={}", offerWorker);
        TbOfferWorkerVO offerWorkerVO = TbOfferWorkerMapstruct.INSTANCE.entity2VO(offerWorker);
        log.info("vo ={}", offerWorkerVO);
        TbOfferAttachment avatarAttachment = SpringUtil.getBean(ITbOfferAttachmentService.class).getOne(new QueryWrapper<TbOfferAttachment>().lambda()
                .eq(TbOfferAttachment::getFileType, TbOfferAttachment.WORK_CARD_PHOTO)
                .eq(TbOfferAttachment::getWorkerId, offerWorkerVO.getWorkerId())
        );
        if (Objects.nonNull(avatarAttachment)) {
            offerWorkerVO.setAvatar(avatarAttachment.getFileId());
            offerWorkerVO.setAvatarStatus(avatarAttachment.getApprovalStatus());
            offerWorkerVO.setRejectReason(avatarAttachment.getRejectReason());
        }
        return offerWorkerVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String finishFill() {
        TbOfferWorker offerWorker = getById(CommonUtil.getActivUser().getUserId());
        if (!offerWorker.getAlreadySave()) {
            throw new BusinessException(false, 400, "基础信息未保存，请先完善并保存信息");
        }
        OfferWorkerStatusEnum workerStatusEnum;
        List<String> noFillList;
        String backHint;
        if (offerWorker.getWorkerStatus().equals(OfferWorkerStatusEnum.待补充资料)) {
            noFillList = judgeIfFillFinish(true, offerWorker.getInType());
        } else {
            noFillList = judgeIfFillFinish(false, offerWorker.getInType());
        }
        if (noFillList.size() > 0) {
            workerStatusEnum = OfferWorkerStatusEnum.待补充资料;
            backHint = "您的入职信息登记提交成功，请尽快补充";
            for (String noFill : noFillList) {
                backHint = backHint + "【" + noFill + "】 ";
            }
            backHint = backHint + "附件信息。";
            //待补充资料邮件通知
//            sendNoticeMail(offerWorker);
        } else {
            if (!iTbWorkerExperienceService.checkJoinDateAndEndDate(offerWorker.getWorkerId(), offerWorker.getPlanReportDate())) {
                throw new AppBusinessException("您的计划入职日期早于最后一次的工作经历结束时间");
            }
            workerStatusEnum = OfferWorkerStatusEnum.待审核入职资料;
            backHint = "您提交了新员工入职登记信息，请等待管理员审核！";
        }
        updateById(offerWorker.setFillStage(OfferWorkerFillStageEnum.FILL_FINISH).setWorkerStatus(workerStatusEnum));
        approvalRecordService.saveRecord(null,
                TbApprovalRecord.RESERVE_STAFF_SUBMIT,
                offerWorker.getWorkerId(),
                offerWorker.getWorkerId() + "/" + offerWorker.getWorkerName(),
                backHint);
        HashMap<String, String> param = new HashMap<>(1);
        param.put("workerNameAndId", offerWorker.getWorkerName() + "/" + offerWorker.getWorkerId());
        ThreadUtil.execute(() -> {
            if(workerStatusEnum.equals(OfferWorkerStatusEnum.待补充资料)){
                String receiveEmail = EmailUtil.getReceiveEmail(offerWorker.getWorkerId(), false, false, false, true);
                EmailUtil.sendPtEmail(emailSendProperties.getWaitAddTemplateCode(), param, receiveEmail, "提醒员工补充入职资料", null, null);
            }else{
                String receiveEmail = EmailUtil.getReceiveEmail(offerWorker.getWorkerId(), true, true, true, false);
                EmailUtil.sendPtEmail(emailSendProperties.getSubmitInfoTemplateCode(), param, receiveEmail, "预备员工已提交入职信息", null, null);
            }
        });
        return backHint;
    }

    public void sendNoticeMail(TbOfferWorker offerWorker) {
        SdEmailTemplate completeTemplate = emailTemplateService.getById("SUBMIT_TO_COMPLETE");
        SdNoticeRecord noticeRecord = new SdNoticeRecord();
        noticeRecord.setNoticeId(IdWorker.nextId() + "");
        noticeRecord.setFlowId("-1");
        noticeRecord.setTargetEmail(offerWorker.getEmail());
        noticeRecord.setTargetName(offerWorker.getWorkerName());
        noticeRecord.setNoticeType(BusiEnumDefine.NOTICE_TYPE_EMAIL);
        noticeRecord.setNoticeTitle(completeTemplate.getEmailTemplateTitle());
        noticeRecord.setNoticeContent(completeTemplate.getEmailTemplateContent());
        asyncSendMessage.sendMessage(Collections.singletonList(noticeRecord));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmFile() {
        TbOfferWorker offerWorker = getById(CommonUtil.getActivUser().getUserId());
        updateById(offerWorker.setFillStage(OfferWorkerFillStageEnum.FILL_ING));
    }

    @Override
    public String startElectronicSignature(List<String> workerIds) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        ArrayList<TbOfferWorkerBO> params = new ArrayList<>();
        for (String workerId : workerIds) {
            TbOfferWorker offerWorker = getById(workerId);
            if (offerWorker.getWorkerStatus().equals(OfferWorkerStatusEnum.待签合同)) {
                if (StringUtils.isBlank(offerWorker.getContractType()) ||
                        Objects.isNull(offerWorker.getContractBeginDate()) ||
                        Objects.isNull(offerWorker.getContractEndDate()) ||
                        Objects.isNull(offerWorker.getProbationMonth())) {
                    throw new AppBusinessException("请先完善工号为:"+offerWorker.getWorkerId()+"的合同相关信息");
                }
                if ("1".equals(offerWorker.getProjectWorkerFlag()) && StringUtils.isEmpty(offerWorker.getProjectWorkCity())) {
                    throw new AppBusinessException("请先联系BP完善工号为:"+offerWorker.getWorkerId() + "的项目制工作地");
                }
                TbOfferWorkerBO offerWorkerBO = TbOfferWorkerMapstruct.INSTANCE.entity2BO(offerWorker);
                offerWorkerBO.setCompanyName(personnelRegisterMiddleService.getCompanyNameByPersonnelCode(offerWorkerBO.getPersonnelRangeCode()));
                params.add(offerWorkerBO);
            }
        }
        ElectronicSignBO electronicSignBO = new ElectronicSignBO();
        electronicSignBO.setAppId("nem-manager");
        electronicSignBO.setSceneType(1);
        HashMap<String, Object> param = new HashMap<>(1);
        param.put("userInfoList", params);
        electronicSignBO.setUserData(JSONUtil.parseObj(JSONUtil.toJsonStr(param)));
        String result = abilityClient.startElectronicSignature(electronicSignBO, request.getHeader("ptToken"));
        return JSONUtil.parseObj(result).getStr("message");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String submitOfGenFormalWorkerId(SubmitFormalWorkerIdDTO dto) {
        TbOfferWorker worker = TbOfferWorkerMapstruct.INSTANCE.submitDtoToEntity(dto);
        updateById(worker);
        TbOfferWorker offerWorker = getById(worker.getWorkerId());
        Date contractBeginDate = offerWorker.getContractBeginDate();
        Integer probationMonth = offerWorker.getProbationMonth();
        dto.setJoinDate(contractBeginDate);
        dto.setProbationMonth(probationMonth);
        if (!Objects.equals(offerWorker.getWorkerStatus(), OfferWorkerStatusEnum.签署完成)
                && !Objects.equals(offerWorker.getWorkerStatus(), OfferWorkerStatusEnum.域账号生成失败)) {
            throw new AppBusinessException("当前预备员工状态不支持生成正式工号");
        }
        Date competitionSignDate = dto.getCompetitionSignDate();
        if ("1".equals(dto.getCompetitionSignFlag())) {
            if (competitionSignDate == null) {
                throw new AppBusinessException("当前员工需选择竞业协议签署日期");
            } else {
                if (competitionSignDate.compareTo(contractBeginDate) < 0) {
                    throw new AppBusinessException("当前员工竞业协议签署日期不能早于入职日期(" + DateUtil.format(contractBeginDate, "y-M-d") + ")");
                }
            }
        }
        //2022/8/4 此校验移到员工填写提交处
//        if (!iTbWorkerExperienceService.checkJoinDateAndEndDate(worker.getWorkerId(), contractBeginDate)) {
//            throw new AppBusinessException("当前预备员工入职日期早于最后一次的工作经历结束时间");
//        }
        if (Objects.equals(offerWorker.getWorkerStatus(), OfferWorkerStatusEnum.域账号生成失败)) {
            Thread account = new Thread(() -> iTbOfferWorkerService.genAccountDomain(offerWorker));
            threadPoolService.submitTask(account);
            return "正在重新尝试生成域账号";
        }
        if (RedisUtil.hasKey(BusiEnumDefine.REDIS_FORMAL_WORKER_ID + dto.getWorkerId())) {
            throw new AppBusinessException("请求正在处理,请勿重复申请生成正式工号");
        } else {
            RedisUtil.setEx(BusiEnumDefine.REDIS_FORMAL_WORKER_ID + dto.getWorkerId(), "1", 10, TimeUnit.MINUTES);
        }
        String workerId = offerWorker.getWorkerId();
        try {
            rfcManager.connect();
            JCoDestination destination = rfcManager.getDestination();
            JCoFunction function = rfcManager.getFunction(destination, "ZRFC_YGRZ_CREATE");//调用SAP接口
            JCoParameterList importParameter = function.getImportParameterList();
            importParameter.setValue("PERNRY", offerWorker.getWorkerId());
            setObject(importParameter, offerWorker);

            JCoParameterList addParam = function.getTableParameterList();//获取表格参数

            JCoTable table1 = addParam.getTable("IT_JTCY");  //获取输入表T_INPUT的数据参数
            setTable1(table1, workerId);

            JCoTable table2 = addParam.getTable("IT_XXJL");
            setTable2(table2, workerId);

            JCoTable table3 = addParam.getTable("IT_GZJL");
            setTable3(table3, workerId);

            JCoTable table4 = addParam.getTable("IT_WYNL");
            setTable4(table4, workerId);

            JCoTable table6 = addParam.getTable("IT_JLQ");
            setTable6(table6, offerWorker);

            function.execute(destination);


            //获取输出表T_OUTPUT的数据
            JCoParameterList exportParameterList = function.getExportParameterList();
            sdRequestRecordService.addReqRecord(workerId, RequestEnum.生成正式工号.getName(), RequestEnum.生成正式工号.getUrl(), importParameter.toXML() + "/n" + addParam.toXML(), exportParameterList.toXML());
            String resCode = exportParameterList.getString("ZMSGTY");
            String regularWorkerId = exportParameterList.getString("PERNR");
            log.info("正式工号生成接口：返回-{}, 正式工号-{}", resCode, regularWorkerId);
            if (StringUtils.isNotBlank(regularWorkerId) && !"00000000".equals(regularWorkerId)) {
                String empCode = CommonUtil.GetEmpCodeTo5(regularWorkerId);
                offerWorker.setRegularWorkerId(empCode);
                updateById(offerWorker);
                Thread account = new Thread(() -> iTbOfferWorkerService.genAccountDomain(offerWorker));
                Thread syncWorker = new Thread(() -> beiSenService.syncWorkerStatusToBeiSen(offerWorker));
                threadPoolService.submitTask(account);
                threadPoolService.submitTask(syncWorker);
                // 异步同步员工手机号码到HRSS
                String sapToken = commService.getSapToken(appId, curSecret);
                asyncSyncDataToHRSS.insertEmpTel(empCode, offerWorker.getPhoneNo(), sapToken);

            } else {
                log.error(exportParameterList.getString("ZMSG"));
                throw new AppBusinessException(exportParameterList.getString("ZMSG"));
            }
        } catch (Exception e) {
            log.error("生成正式工号异常：", e);
            if (e instanceof AppBusinessException) {
                throw (AppBusinessException) e;
            }
            throw new AppBusinessException("生成正式工号异常");
        } finally {
            RedisUtil.delete(BusiEnumDefine.REDIS_FORMAL_WORKER_ID + dto.getWorkerId());
        }
        return "SUCCESS";
    }

    public void genAccountDomain(TbOfferWorker offerWorker) {
        String workerId = offerWorker.getWorkerId();
        try {
            if (RedisUtil.hasKey(BusiEnumDefine.REDIS_DOMAIN_ACCOUNT + workerId)) {
                throw new AppBusinessException("请求正在处理,请勿重复申请生成域账号");
            } else {
                RedisUtil.setEx(BusiEnumDefine.REDIS_DOMAIN_ACCOUNT + workerId, "1", 10, TimeUnit.MINUTES);
            }
            SdDept dept = iSdDeptService.getDeptByNameChain(offerWorker.getDeptNameChain());
            String deptCodeChain = dept.getDeptCodeChain();
            String deptNameChain = dept.getDeptNameChain();
            String[] codes = deptCodeChain.split("/");
            String[] names = deptNameChain.split("/");

            Map<String, String> user = new HashMap<>();
            user.put("Dept1Code", null);
            user.put("Dept1Name", null);
            user.put("Dept2Code", null);
            user.put("Dept2Name", null);
            user.put("Dept3Code", null);
            user.put("Dept3Name", null);
            if (names.length >= 2) {
                SdDept sdDept = commService.getSdDept(codes[1]);
                user.put("Dept1Code", sdDept.getCoaCode());
                user.put("Dept1Name", names[1]);
                user.put("Dept2Code", sdDept.getCoaCode());
                user.put("Dept2Name", names[1]);
                user.put("Dept3Code", sdDept.getCoaCode());
                user.put("Dept3Name", names[1]);
            }
            if (names.length >= 3) {
                SdDept sdDept = commService.getSdDept(codes[2]);
                user.put("Dept2Code", sdDept.getCoaCode());
                user.put("Dept2Name", names[2]);
                user.put("Dept3Code", sdDept.getCoaCode());
                user.put("Dept3Name", names[2]);
            }
            if (names.length >= 4) {
                SdDept sdDept = commService.getSdDept(codes[3]);
                user.put("Dept3Code", sdDept.getCoaCode());
                user.put("Dept3Name", names[3]);
            }
            user.put("EmployeeCode", offerWorker.getRegularWorkerId());
            user.put("FirstName", offerWorker.getFirstPinyin());
            user.put("LastName", offerWorker.getLastPinyin());
            user.put("PublicYuHao", "hrssadmin");
            user.put("EmailAddress", offerWorker.getEmail());
            //103100研发103101非研发
            user.put("WorkPlace", "1".equals(offerWorker.getWorkLocation()) ? "103100" : "103101");
            user.put("OverSeasRegion", null);
            user.put("GWSamAccount", null);
            user.put("GWEmail", null);

            JSONObject jsonObject = new JSONObject();
            JSONArray array = new JSONArray();
            array.add(user);
            log.info("生成域账号参数：{}", user);
            jsonObject.put("user", array);

            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<JSONObject> reqEntity = new HttpEntity<>(jsonObject, httpHeaders);
            ResponseEntity<String> resEntity = restTemplate.exchange(admpUrl, HttpMethod.POST, reqEntity, String.class);
            log.info("生成域账号接口返回：{}", resEntity);
            String res = StringUtils.isBlank(resEntity.getBody()) ? "" : resEntity.getBody();
            String body = res.replace("\"[", "").replace("]\"", "").replace("\\\"", "\"");
            JSONObject result = JSONObject.parseObject(body);
            String errorCode = result.getString("ErrorCode");
            String message = result.getString("ErrorMessage");
            String samAccount;
            if ("3".equals(errorCode) && message.contains("重复")) {
                samAccount = offerWorker.getDomainAccount();
            } else {
                samAccount = result.getString("SamAccount");
            }
            if (StringUtils.isNotBlank(samAccount)) {
                //更新offerWorker
                offerWorker.setDomainAccount(samAccount);
                updateById(offerWorker);

                String emailAddress = result.getString("EmailAddress") + "@h3c.com";
                String userPwd = result.getString("UserPwd");
                String contactorName = dept.getContactorName();

                Thread thread = new Thread(() -> sendEmailAndSms(offerWorker, samAccount, emailAddress, userPwd, contactorName));
                threadPoolService.submitTask(thread);

                //生成本地数据 allWorker tbWorker
                iSdAllWorkerService.updateAllWorkerOfOfferWorker(offerWorker, codes, emailAddress, samAccount);
                iTbWorkerService.insertOfferWorkerIntoWorker(offerWorker);
                offerWorker.setWorkerStatus(OfferWorkerStatusEnum.已入职);
                updateById(offerWorker);
            } else {
                offerWorker.setWorkerStatus(OfferWorkerStatusEnum.域账号生成失败);
                updateById(offerWorker);
                log.error(message);
                log.error(offerWorker.getWorkerName() + "/" + workerId + "的域账号生成失败");
            }
        } catch (Exception e) {
            log.error(offerWorker.getWorkerName() + "/" + workerId + "的域账号生成异常:", e);
            offerWorker.setWorkerStatus(OfferWorkerStatusEnum.域账号生成失败);
            updateById(offerWorker);
        } finally {
            RedisUtil.delete(BusiEnumDefine.REDIS_DOMAIN_ACCOUNT + workerId);
        }
    }

    public void sendEmail(TbOfferWorker offerWorker, String samAccount, String emailAddress, String userPwd, String contactorName){
        String regularWorkerId = offerWorker.getRegularWorkerId();
        String workerId = offerWorker.getWorkerId();
        SdEmailTemplate template = emailTemplateService.getById("ELECTRONIC_SIGNATURE_DOCUMENT");
        String templateContent = template.getEmailTemplateContent();
        String templateTitle = template.getEmailTemplateTitle();
        log.info("用户id为" + offerWorker.getWorkerId());

        // 判断员工类型，并添加不同邮件内容

        boolean needSendEmail = false;
        List<PtEsignRecordInfoVO> tbOfferRecord = abilityClient.getTbOfferRecord(offerWorker.getWorkerId(), 1);
        log.info("员工{}", tbOfferRecord);
        if (!CollectionUtils.isEmpty(tbOfferRecord)) {
            int index = 1;
            for (PtEsignRecordInfoVO vo : tbOfferRecord) {
                if (vo.getSfsId() != null) {
                    needSendEmail = true;
                    String id = vo.getSfsId();
                    String fileName = vo.getTemplateName();
                    String originalAddress = downloadPath + "/ptability-manage/v1.0/ptUploadFile/downloadFileEncryption?fileId={}";
                    originalAddress = StrUtil.format(originalAddress, EncryptionUtil.getEncryptDataAES(id));
                    String inputMessage =  "<p>" + index + " " + fileName + "下载链接为" + originalAddress + "<br></p>";
                    templateContent += inputMessage;
                    index++;
                }
            }

            if (needSendEmail) {
                //短信
                SdNoticeRecord smsRecord = iSdNoticeRecordService.createSmsNoticeRecord(workerId, offerWorker.getWorkerName(),
                        offerWorker.getPhoneNo(), templateTitle, templateContent);
                asyncSendMessage.sendMessage(Collections.singletonList(smsRecord));
                //邮件
                SdNoticeRecord emailRecord = iSdNoticeRecordService.createEmailNoticeRecord("-1", workerId, offerWorker.getWorkerName(),
                        emailAddress, templateTitle, templateContent, "");
                asyncSendMessage.sendMessage(Collections.singletonList(emailRecord));
            }
        }
    }

    private void sendEmailAndSms(TbOfferWorker offerWorker, String samAccount, String emailAddress, String userPwd, String contactorName) {
        String regularWorkerId = offerWorker.getRegularWorkerId();
        String workerId = offerWorker.getWorkerId();
        //发送短信和邮件给预备员工
        SdEmailTemplate template = emailTemplateService.getById("GEN_ACCOUNT_DOMAIN_TEMPLATE");
        String templateContent = template.getEmailTemplateContent();
        String templateTitle = template.getEmailTemplateTitle();
        templateContent = templateContent.replace("{正式工号}", regularWorkerId)
                .replace("{域账号}", samAccount)
                .replace("{公司邮箱}", emailAddress)
                .replace("{初始密码}", userPwd)
                .replace("{直接主管}", offerWorker.getDirectManager() == null ? "" : offerWorker.getDirectManager())
                .replace("{部门接口人}", contactorName == null ? "" : contactorName);

        //短信
        log.info(" 生成域账号后消息内容：{}",templateContent);
        SdNoticeRecord smsRecord = iSdNoticeRecordService.createSmsNoticeRecord(workerId, offerWorker.getWorkerName(),
                offerWorker.getPhoneNo(), templateTitle, templateContent);
        asyncSendMessage.sendMessage(Collections.singletonList(smsRecord));
        log.info(" 生成域账号后发短信");
        //邮件
        SdNoticeRecord emailRecord = iSdNoticeRecordService.createEmailNoticeRecord("-1", workerId, offerWorker.getWorkerName(),
                emailAddress, templateTitle, templateContent, "");
        asyncSendMessage.sendMessage(Collections.singletonList(emailRecord));
        log.info(" 生成域账号后发邮件");
        //发送给部门接口人、直接上级和思想导师
        SdEmailTemplate teacherAndManager = emailTemplateService.getById("SEND_TO_TEACHER_AND_MANAGER");
        String tamTitle = teacherAndManager.getEmailTemplateTitle();
        String tamContent = teacherAndManager.getEmailTemplateContent();
        //您好，如下新员工今天已经入职完成，请做好新员工接待和工作安排。
        //{员工信息姓名/正式工号 报到日期：2022-06-22 部门：信息技术部/AI及中台部/数据平台部 电话：13563666987；...}
        tamContent = tamContent.replace("{员工姓名/正式工号}", offerWorker.getWorkerName() + "/" + offerWorker.getRegularWorkerId())
                .replace("{报到日期}", com.h3c.nem.utils.DateUtil.getDateStr(offerWorker.getContractBeginDate()))
                .replace("{部门名称}", offerWorker.getDeptNameChain()).replace("{手机号}", offerWorker.getPhoneNo());

        //找到需要发送的接口人、导师、直接主管
        String emailTargetUser = iSdDeptService.getContactorByDeptNameChain(offerWorker.getDeptNameChain(), offerWorker.getWorkCity());
        String teacherInfo = offerWorker.getTeacherInfo();
        String directManager = offerWorker.getDirectManager();
        String teacherId;
        if (StringUtils.isNotBlank(teacherInfo)) {
            teacherId = teacherInfo.split("/")[1];
            emailTargetUser = emailTargetUser + "," + teacherId;
        }
        String managerId;
        if (StringUtils.isNotBlank(directManager)) {
            managerId = directManager.split("/")[1];
            emailTargetUser = emailTargetUser + "," + managerId;
        }
        log.info(" 预备员工正式工号功能，邮件收送人：{}", emailTargetUser);
        if (StringUtils.isNotBlank(emailTargetUser)) {
            Map<String, String> map = iSdDeptService.getWorkerMap(emailTargetUser);
            String targetIds = map.get("ids");
            String targetNames = map.get("names");
            String targetEmails = map.get("emails");
            //邮件
            SdNoticeRecord toEmailRecord = iSdNoticeRecordService.createEmailNoticeRecord("-1", targetIds,
                    targetNames, targetEmails, tamTitle, tamContent, "");
            asyncSendMessage.sendMessage(Collections.singletonList(toEmailRecord));
            //企微消息
            SdNoticeRecord qwNoticeRecord = iSdNoticeRecordService.createQwNoticeRecord(targetIds, targetNames, tamTitle, tamContent);
            List<String> accountId = commService.getAccountByWorkerId(targetIds);
            asyncSendMessage.sendMessage(qwNoticeRecord, null, accountId);
        }
        sendEmail(offerWorker, samAccount, emailAddress, userPwd, contactorName);
    }

    @Override
    @SneakyThrows
    public void refuseOffer(String workerId, HttpServletResponse response) {
        String realWorkerId = EncryptionUtil.getDecryptDataAES(workerId);
        TbOfferWorker offerWorker = getById(realWorkerId);
        if (Objects.isNull(offerWorker)) {
            return;
        }
        if (offerWorker.getWorkerStatus().getCode() <= OfferWorkerStatusEnum.待签合同.getCode()
                && !offerWorker.getOfferStatus().equals(OfferWorkerOfferStatusEnum.REFUSE_OFFER)
        ) {
            updateById(new TbOfferWorker()
                    .setWorkerId(realWorkerId)
                    .setWorkerStatus(OfferWorkerStatusEnum.放弃入职)
                    .setOfferStatus(OfferWorkerOfferStatusEnum.REFUSE_OFFER)
            );
            HashMap<String, String> param = new HashMap<>(1);
            param.put("workerNameAndId", offerWorker.getWorkerName() + "/" + offerWorker.getWorkerId());
            ThreadUtil.execute(() -> {
                String receiveEmail = EmailUtil.getReceiveEmail(offerWorker.getWorkerId(), true, true, false, false);
                EmailUtil.sendPtEmail(emailSendProperties.getRefuseTemplateCode(), param, receiveEmail, "预备员工拒绝offer", null, null);
            });
        }
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
        response.sendRedirect(emailSendProperties.getRefuseJumpUrl());
    }

    @Override
    @SneakyThrows
    public void acceptOffer(String workerId, HttpServletResponse response) {
        String realWorkerId = EncryptionUtil.getDecryptDataAES(workerId);
        TbOfferWorker offerWorker = getById(realWorkerId);
        if (Objects.isNull(offerWorker)) {
            return;
        }
        if (offerWorker.getOfferStatus().equals(OfferWorkerOfferStatusEnum.SEND_OFFER)) {
            updateById(new TbOfferWorker()
                    .setWorkerId(realWorkerId)
                    .setOfferStatus(OfferWorkerOfferStatusEnum.ACCEPT_OFFER)
            );
            sendMailWhenAccept(offerWorker);
        }
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
        response.sendRedirect(emailSendProperties.getAcceptJumpUrl());
    }

    public void sendMailWhenAccept(TbOfferWorker offerWorker) {
        String directManager = offerWorker.getDirectManager();
        String deptNameChain = offerWorker.getDeptNameChain();
        //您好，您负责部门的{候选人}（手机号{手机号}）已经接受offer，计划入职日期为{日期}，您可点击链接进入系统查看该员工相关信息。
        SdEmailTemplate template = emailTemplateService.getById("MAIL_WHEN_ACCEPT_OFFER");
        String title = template.getEmailTemplateTitle();
        String content = template.getEmailTemplateContent();
        title = title.replace("{候选人}", offerWorker.getWorkerName());
        content = content.replace("{候选人}", offerWorker.getWorkerName())
                .replace("{手机号}", offerWorker.getPhoneNo());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date planReportDate = offerWorker.getPlanReportDate();
        if (planReportDate != null) {
            String format = sdf.format(planReportDate);
            String week = com.h3c.nem.utils.DateUtil.dateToWeek(planReportDate);
            content = content.replace("{日期}", format + "("+week+")");
        } else {
            content = content.replace("{日期}", " 暂无");
        }
        String targetId = "";
        String targetName = "";
        String targetMail = "";
        if (!StringUtils.isEmpty(directManager)) {
            SdAllWorker leader = commService.getAllWorkerDoFromLocalCache(directManager.split("/")[1]);
            if (leader != null) {
                targetId = leader.getWorkerId();
                targetName = leader.getWorkerName();
                targetMail = leader.getEmail();
            }
        } else if (!StringUtils.isEmpty(deptNameChain)) {
            SdDept dept = iSdDeptService.getDeptByNameChainNoException(deptNameChain);
            if (dept != null) {
                String leaderId = dept.getDeptManagerId();
                if (!StringUtils.isEmpty(leaderId)) {
                    SdAllWorker leader = commService.getAllWorkerDoFromLocalCache(leaderId.split(",")[0]);
                    if (leader != null) {
                        targetId = leader.getWorkerId();
                        targetName = leader.getWorkerName();
                        targetMail = leader.getEmail();
                    }
                }
            }
        }
        if (!StringUtils.isEmpty(targetMail)) {
            SdNoticeRecord mailRecord = iSdNoticeRecordService.createMailRecord(offerWorker.getWorkerId(), targetId, targetName, targetMail, title, content);
            asyncSendMessage.sendMessage(Collections.singletonList(mailRecord));
        }
    }

    /**
     * 获取电子签文件
     *
     * @return
     */
    public List<File> getEsignFileList(String workerId) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("workerId", workerId);
        jsonObject.put("sceneType", "1");
        JSONObject result = abilityClient.esignRecord(jsonObject, ptToken);
        String status = result.getString("status");
        if (Objects.equals(status, "200")) {
            Object data = result.get("data");
            List<String> sfsIdList = (List<String>) data;
            List<File> fileRes = new ArrayList<>();
            for (String sfsId : sfsIdList) {
                JSONObject fileResult = abilityClient.downloadFile(sfsId, "合同.pdf", offerWorkerProperties.getDownloadSfsAccount());
                String fileBase64 = fileResult.getJSONObject("data").getString("file");
                String fileName = fileResult.getJSONObject("data").getString("filename");
                File temp = FileUtil.writeBytes(Base64.decode(fileBase64), "download/" + fileName + ".pdf");
                fileRes.add(temp);
            }
            return fileRes;
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserInfoByOCR(OcrDTO ocrDTO) {
        TbOfferWorker offerWorker = getById(CommonUtil.getActivUser().getUserId());
        offerWorker.setWorkerName(ocrDTO.getName());
        offerWorker.setSex(ocrDTO.getSex());
        offerWorker.setBirthday(DateUtil.parse(ocrDTO.getBirth()));
//        offerWorker.setNation(ocrDTO.getNation());
        offerWorker.setWorkerId(CommonUtil.getActivUser().getUserId());
        updateById(offerWorker);
        attachmentService.update(null, new LambdaUpdateWrapper<TbOfferAttachment>()
                .set(TbOfferAttachment::getAlreadySave, true)
                .eq(TbOfferAttachment::getWorkerId, CommonUtil.getActivUser().getUserId())
                .eq(TbOfferAttachment::getFileType, 4)
        );
        TbOfferWorkerCache.updateFillStatus(CommonUtil.getActivUser().getUserId(), TbOfferWorkerCache.ATTACHMENT);
    }

    @Override
    public String editPendingEmployees(OfferWorkerEditDTO dto) {
        boolean haveAuth = commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_ADMIN)
                || commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_OFFER_SSC_MANAGER)
                || commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_OFFER_DEPT_MANAGER);
        if (!haveAuth) {
            throw new AppBusinessException(StatusCodeEnum.UN_AUTH.getMassage());
        }

        TbOfferWorker offerWorker = getById(dto.getWorkerId());
        OfferWorkerStatusEnum.lessCodeEditInformation(offerWorker.getWorkerStatus());
        String contractType = dto.getContractType();
        String contractBeginDate = dto.getContractBeginDate();
        String contractEndDate = dto.getContractEndDate();
        String probationMonth = dto.getProbationMonth();
        UpdateWrapper<TbOfferWorker> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(TbOfferWorker::getContractType, contractType)
                .set(TbOfferWorker::getContractBeginDate, contractBeginDate)
                .set(TbOfferWorker::getJoinDate, contractBeginDate)
                .set(TbOfferWorker::getContractEndDate, contractEndDate)
                .set(TbOfferWorker::getProbationMonth, probationMonth)
                .eq(TbOfferWorker::getWorkerId, dto.getWorkerId());
        update(updateWrapper);
        return "SUCCESS";
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String editOfferWorker(OfferWorkerEditDTO dto) {

        //查询用户角色
        boolean haveAuth = commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_ADMIN)
                || commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_NEW_WORKER_BP)
                || commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_OFFER_BP)
                || commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_DEPT_CONTACTOR);
        if (!haveAuth) {
            throw new AppBusinessException(StatusCodeEnum.UN_AUTH.getMassage());
        }

        //员工入职状态
        TbOfferWorker checkStatus = getById(dto.getWorkerId());
        OfferWorkerStatusEnum.lessCodeEditInformation(checkStatus.getWorkerStatus());

        Date planReportDate = dto.getPlanReportDate();
        boolean sendFlag = false;

        TbOfferWorker workerOri = getById(dto.getWorkerId());
        if (workerOri != null && !Objects.equals(planReportDate, workerOri.getPlanReportDate())) {
            if (workerOri.getWorkerStatus().getCode() >= OfferWorkerStatusEnum.待签合同.getCode()
                    && !commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_ADMIN)) {
                throw new AppBusinessException("员工资料已通过审核，不可再修改计划入职日期，如有需要请联系SSC");
            }
            sendFlag = true;
        }

        String directManagerId = dto.getDirectManager();
        if (!StringUtils.isEmpty(directManagerId) && directManagerId.contains("/")) {
            directManagerId = directManagerId.split("/")[1];
        }

        String phoneNo = dto.getPhoneNo();
        String nameChain = dto.getDeptNameChain();
        String teacherId = dto.getTeacherInfo();
        String projectWorkCity = dto.getProjectWorkCity();

        SdAllWorker teacherWorker = commService.getAllWorkerDoFromLocalCache(teacherId);
        String teacherInfo;
        if (teacherWorker == null) {
            teacherInfo = "";
        } else {
            teacherInfo = teacherWorker.getWorkerName() + "/" + teacherId;
        }
        SdAllWorker managerWorker = commService.getAllWorkerDoFromLocalCache(directManagerId);
        if (managerWorker == null) {
            throw new AppBusinessException("直接主管输入有误，查询失败");
        }

        UpdateWrapper<TbOfferWorker> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(TbOfferWorker::getWorkerId, dto.getWorkerId());

        TbOfferWorker offerWorker = new TbOfferWorker();
        offerWorker.setPhoneNo(phoneNo);
        offerWorker.setPlanReportDate(planReportDate);
        offerWorker.setDeptNameChain(nameChain);
        offerWorker.setTeacherInfo(teacherInfo);
        offerWorker.setProjectWorkCity(projectWorkCity);
        offerWorker.setDirectManager(managerWorker.getWorkerName() + "/" + directManagerId);
        //考勤相关
        offerWorker.setSignInFlag("9");
        offerWorker.setFlexibleFlag("02");
        offerWorker.setWorkOrder(dto.getWorkOrder());
        offerWorker.setCheckWorkType(dto.getCheckWorkType());
        offerWorker.setResearchFlag(dto.getResearchFlag());
        offerWorker.setWorkLocation(dto.getWorkLocation());

        String[] deptNameArr = nameChain.split("/");
        if (deptNameArr.length > 0) {
            offerWorker.setDept1name(deptNameArr[0]);
        }
        if (deptNameArr.length > 1) {
            offerWorker.setDept2name(deptNameArr[1]);
        }
        if (deptNameArr.length > 2) {
            offerWorker.setDept3name(deptNameArr[2]);
        }
        if (deptNameArr.length > 3) {
            offerWorker.setDept4name(deptNameArr[3]);
        }
        update(offerWorker, updateWrapper);
        TbOfferWorker workerUpdated = getById(dto.getWorkerId());
        if (sendFlag) {
            String loginUserIdAndName = commService.getLoginUserIdAndName();
            SdEmailTemplate updatePlanDateSmsTemplate = emailTemplateService.getById("UPDATE_PLAN_DATE_SMS");
            String title = updatePlanDateSmsTemplate.getEmailTemplateTitle();
            String content = updatePlanDateSmsTemplate.getEmailTemplateContent();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String planStr = dateFormat.format(workerUpdated.getPlanReportDate());
            //您好，招聘接口人将您的计划报到日期修改为 2022-06-21，请按新的计划报到日期按时报到，非常感谢！如需变更可通过入职登记平台进行申请。
            content = content.replace("{计划入职日期}", planStr);
            SdNoticeRecord smsNoticeRecord = iSdNoticeRecordService.createSmsNoticeRecord(workerUpdated.getWorkerId(),
                    workerUpdated.getWorkerName(), workerUpdated.getPhoneNo(), title, content);

            //您好，预备员工 张三/92363365 的计划报到日期已经被修改为 2022-06-21，请知悉。您可登录新员工系统关注预备员工最新动态。谢谢！
            //newemployee.h3c.com
            SdEmailTemplate updatePlanDateEmailTemplate = emailTemplateService.getById("UPDATE_PLAN_DATE_EMAIL");
            String emailTitle = updatePlanDateEmailTemplate.getEmailTemplateTitle();
            String emailContent = updatePlanDateEmailTemplate.getEmailTemplateContent();
            emailContent = emailContent.replace("{员工姓名/工号}", workerUpdated.getWorkerId() + "/" + workerUpdated.getWorkerName())
                    .replace("{操作人}", loginUserIdAndName)
                    .replace("{计划入职日期}", planStr);

            Map<String, String> map = iSdDeptService.getBpAndContactorAndSSC(workerUpdated.getDeptNameChain(), workerUpdated.getWorkCity());
            if (!map.isEmpty()) {
                SdNoticeRecord emailNoticeRecord = iSdNoticeRecordService.createEmailNoticeRecord("-1", map.get("ids"),
                        map.get("names"), map.get("emails"), emailTitle, emailContent, "");
                asyncSendMessage.sendMessage(Arrays.asList(smsNoticeRecord, emailNoticeRecord));
            }

            //日期变更通知主管
            //您好，您负责部门的{候选人}（手机号{手机号}）计划入职日期从{原日期}变更为{新日期}，您可点击链接进入系统查看该员工相关信息。
            SdEmailTemplate leaderTemplate = emailTemplateService.getById("MAIL_WHEN_REPORT_DATE");
            String leaderTitle = leaderTemplate.getEmailTemplateTitle();
            String leaderContent = leaderTemplate.getEmailTemplateContent();
            leaderTitle = leaderTitle.replace("{候选人}", workerUpdated.getWorkerName());
            leaderContent = leaderContent.replace("{候选人}",workerUpdated.getWorkerName())
                    .replace("{手机号}", workerUpdated.getPhoneNo())
                    .replace("{新日期}", dateFormat.format(workerUpdated.getPlanReportDate()) + "("+com.h3c.nem.utils.DateUtil.dateToWeek(workerUpdated.getPlanReportDate()) + ")");
            if (workerOri.getPlanReportDate() == null) {
                leaderContent = leaderContent.replace("{原日期}", "暂无");
            } else {
                leaderContent = leaderContent.replace("{原日期}", dateFormat.format(workerOri.getPlanReportDate()));
            }
            Map<String, String> leaderInfo = getLeaderInfo(workerUpdated);
            String leaderMail = leaderInfo.get("mail");
            if (!StringUtils.isEmpty(leaderMail)) {
                String leaderId = leaderInfo.get("id");
                String leaderName = leaderInfo.get("name");
                SdNoticeRecord mailRecord = iSdNoticeRecordService.createMailRecord(workerUpdated.getWorkerId(), leaderId, leaderName, leaderMail, leaderTitle, leaderContent);
                asyncSendMessage.sendMessage(Collections.singletonList(mailRecord));
            }

        }
        return "SUCCESS";
    }

    public Map<String, String> getLeaderInfo(TbOfferWorker offerWorker) {
        String directManager = offerWorker.getDirectManager();
        String deptNameChain = offerWorker.getDeptNameChain();
        String targetId = "";
        String targetName = "";
        String targetMail = "";
        if (!StringUtils.isEmpty(directManager)) {
            SdAllWorker leader = commService.getAllWorkerDoFromLocalCache(directManager.split("/")[1]);
            if (leader != null) {
                targetId = leader.getWorkerId();
                targetName = leader.getWorkerName();
                targetMail = leader.getEmail();
            }
        } else if (!StringUtils.isEmpty(deptNameChain)) {
            SdDept dept = iSdDeptService.getDeptByNameChainNoException(deptNameChain);
            if (dept != null) {
                String leaderId = dept.getDeptManagerId();
                if (!StringUtils.isEmpty(leaderId)) {
                    SdAllWorker leader = commService.getAllWorkerDoFromLocalCache(leaderId.split(",")[0]);
                    if (leader != null) {
                        targetId = leader.getWorkerId();
                        targetName = leader.getWorkerName();
                        targetMail = leader.getEmail();
                    }
                }
            }
        }

        Map<String, String> map = new HashMap<>();
        map.put("id", targetId);
        map.put("name", targetName);
        map.put("mail", targetMail);
        return map;
    }

    @Override
    public String batchSubmitOfGenFormalWorkerId(SubmitFormalWorkerIdDTO worker) {
        StringBuilder result = new StringBuilder();
        String workerId = worker.getWorkerId();
        List<String> ids = Arrays.asList(workerId.split(","));
        List<TbOfferWorker> list = list(new LambdaQueryWrapper<TbOfferWorker>().in(TbOfferWorker::getWorkerId, ids));
        String offerWorkerList = list.stream()
                .filter(o -> !Objects.equals(o.getWorkerStatus(), OfferWorkerStatusEnum.签署完成)
                        && !Objects.equals(o.getWorkerStatus(), OfferWorkerStatusEnum.域账号生成失败))
                .map(TbOfferWorker::getWorkerName)
                .collect(Collectors.joining(","));
        if (StringUtils.isNotBlank(offerWorkerList)) {
            throw new AppBusinessException("当前预备员工" + offerWorkerList + "状态不支持生成正式工号");
        }
        for (String id : ids) {
            TbOfferWorker offerWorker = getById(id);
            String deptNameChain = offerWorker.getDeptNameChain();
            SdDept dept = iSdDeptService.getDeptByNameChain(deptNameChain);
            String deptType = dept.getDeptType();
            SubmitFormalWorkerIdDTO workerDTO = new SubmitFormalWorkerIdDTO();
            BeanUtils.copyProperties(worker, workerDTO);
            workerDTO.setWorkerId(id);
            if (Objects.equals(deptType, "RD")) {
                workerDTO.setWorkOrder("FLXA");
                workerDTO.setResearchFlag("1"); //研发
                workerDTO.setWorkLocation("1"); //研发
            } else {
                workerDTO.setWorkOrder("FLXB");
                workerDTO.setResearchFlag("2"); //非研发
                workerDTO.setWorkLocation("0"); //非研发
            }
            //批量生成正式工号时如果原本设置了研发非研发则用设置了的值
            if (!StringUtils.isEmpty(offerWorker.getWorkOrder())) {
                workerDTO.setWorkOrder(offerWorker.getWorkOrder());
            }
            if (!StringUtils.isEmpty(offerWorker.getResearchFlag())) {
                workerDTO.setResearchFlag(offerWorker.getResearchFlag());
            }
            if (!StringUtils.isEmpty(offerWorker.getWorkLocation())) {
                workerDTO.setWorkLocation(offerWorker.getWorkLocation());
            }
            workerDTO.setFlexibleFlag("02"); //弹性班次
            workerDTO.setSignInFlag("9"); //免刷卡
            workerDTO.setJoinDate(offerWorker.getContractBeginDate());
            workerDTO.setCheckWorkType("02"); //手工考勤
            try {
                iTbOfferWorkerService.submitOfGenFormalWorkerId(workerDTO);
            } catch (Exception e) {
                String message = e.getMessage();
                result.append(workerDTO.getWorkerId()).append("/").append(offerWorker.getWorkerName()).append(":")
                        .append(message).append("\n");
            }
        }
        return result.toString();
    }

    public JSONObject checkRdDeptTypeAndManager(String deptNameChain) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("deptType", false);
        jsonObject.put("manager", "");
        if (!StringUtils.isEmpty(deptNameChain)) {
            SdDept dept = iSdDeptService.getDeptByNameChainNoException(deptNameChain);
            if (dept != null) {
                jsonObject.put("deptType", "RD".equals(dept.getDeptType()));
                String deptManagerName = dept.getDeptManagerName();
                if (!StringUtils.isEmpty(deptManagerName)) {
                    jsonObject.put("manager", deptManagerName.split(",")[0]);
                }
            }
        }
        return jsonObject;
    }

    @Override
    public void postalReminder(String workerIds) {
        if (StringUtils.isBlank(workerIds)) {
            throw new AppBusinessException("参数异常");
        }
        SdEmailTemplate startTemplate = emailTemplateService.getById("OFFER_WORKER_POSTAL_REMINDER");
        //发送邮件
        List<SdNoticeRecord> noticeList = new ArrayList<>();
        List<String> workerIdsList = Arrays.asList(workerIds.split(","));
        workerIdsList.forEach(wid -> {
            TbOfferWorker tbOfferWorker = getById(wid);
            OfferWorkerStatusEnum workerStatus = tbOfferWorker.getWorkerStatus();
            if (!OfferWorkerStatusEnum.待填写入职资料.equals(workerStatus)
                    && !OfferWorkerStatusEnum.待补充资料.equals(workerStatus)) {
                throw new AppBusinessException(wid + "状态不支持邮催");
            }
        });
        List<TbOfferWorker> offerWorkerList = list(new LambdaQueryWrapper<TbOfferWorker>().in(TbOfferWorker::getWorkerId, workerIdsList));
        Map<String, TbOfferWorker> offerWorkerMap = offerWorkerList.stream().collect(Collectors.toMap(TbOfferWorker::getWorkerId, o -> o));
        for (String id : workerIdsList) {
            TbOfferWorker worker = offerWorkerMap.get(id);
            String content = startTemplate.getEmailTemplateContent();
            content = content.replace("{员工姓名}", worker.getWorkerName());
            SdNoticeRecord sdNoticeRecord = iSdNoticeRecordService.createEmailNoticeRecord("-1", worker.getWorkerId(),
                    worker.getWorkerName(), worker.getEmail(), startTemplate.getEmailTemplateTitle(),
                    content, "");
            noticeList.add(sdNoticeRecord);
        }
        asyncSendMessage.sendMessage(noticeList);
    }

    @Override
    public void offerWorkerWillJoinJob(String s) {
        try {
            Date date = new Date();
            Date tomorrow = DateUtils.addDays(date, 1);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String tomorrowStr = dateFormat.format(tomorrow);
            XxlJobLogger.log("明天日期：" + tomorrowStr);
            QueryWrapper<TbOfferWorker> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(TbOfferWorker::getPlanReportDate, dateFormat.parse(tomorrowStr));
            List<TbOfferWorker> list = list(queryWrapper);
            XxlJobLogger.log("明天共有" + list.size() + "名新员工入职");
            if (list.isEmpty()) {
                XxlJobLogger.log("明天无新员工入职，结束");
                return;
            }
            //您好！您管理部门下的如下新员工即将与明天入职，请进入新员工管理系统，核对他们的人事范围、岗位信息、工作履行地、入职日期是否正确，以免影响到后续的电子合同的生成。感谢您的理解和配合！
            //{预备员工信息姓名/工号 预计报到日期：2022-06-22 计划入职部门：信息技术部/AI及中台部/数据平台部；...}
            //newreg.h3c.com
            List<SdNoticeRecord> noticeRecords = new ArrayList<>();
            SdEmailTemplate workerWillJoin = emailTemplateService.getById("OFFER_WORKER_WILL_JOIN");
            String content = workerWillJoin.getEmailTemplateContent();
            String title = workerWillJoin.getEmailTemplateTitle();
            for (TbOfferWorker worker : list) {
                try {
                    String workerId = worker.getWorkerId();
                    String workerName = worker.getWorkerName();
                    String workerNameAndId = workerName + "/" + workerId;
                    String planDateStr = com.h3c.nem.utils.DateUtil.getDateStr(worker.getPlanReportDate());
                    String emailContent = content.replace("{员工姓名/工号}", workerNameAndId)
                            .replace("{计划入职日期}", planDateStr).replace("{部门名称}", worker.getDeptNameChain());
                    Map<String, String> map = iSdDeptService.getBpAndContactorByDeptNameChain(worker.getDeptNameChain(), worker.getWorkCity());
                    SdNoticeRecord emailNoticeRecord = iSdNoticeRecordService.createEmailNoticeRecord("-1", map.get("ids"),
                            map.get("names"), map.get("emails"), title, emailContent, "");
                    noticeRecords.add(emailNoticeRecord);
                } catch (Exception e) {
                    XxlJobLogger.log("发送邮件【" + worker.getWorkerName() + "/" + worker.getWorkerId() + "】失败");
                }
            }
            XxlJobLogger.log("发送邮件" + noticeRecords.size() + "条");
            asyncSendMessage.sendMessage(noticeRecords);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void confirmEsign(String workerId) {
        if (getById(workerId).getWorkerStatus().getCode() >= OfferWorkerStatusEnum.签署完成.getCode()) {
            return;
        }
        updateById(new TbOfferWorker().setWorkerId(workerId).setWorkerStatus(OfferWorkerStatusEnum.签署完成));
    }

    @Override
    public String reSignFile(List<ReSignDTO> reSignDTOS, String appId, Integer sceneType) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        ArrayList<TbOfferWorkerBO> params = new ArrayList<>();
        for (ReSignDTO reSignDTO : reSignDTOS) {
            RedisUtil.delete(StrUtil.format(EsignAckReceiver.ES_SIGN_MQ, reSignDTO.getWorkerId()));
            RedisUtil.delete(StrUtil.format(EmailAckReceiver.EMAIL_MQ, reSignDTO.getWorkerId()));
            TbOfferWorker offerWorker = getById(reSignDTO.getWorkerId());
            offerWorker.setRecordId(reSignDTO.getRecordId());
            TbOfferWorkerBO offerWorkerBO = TbOfferWorkerMapstruct.INSTANCE.entity2BO(offerWorker);
            offerWorkerBO.setCompanyName(personnelRegisterMiddleService.getCompanyNameByPersonnelCode(offerWorkerBO.getPersonnelRangeCode()));
            params.add(offerWorkerBO);
        }
        ElectronicSignBO electronicSignBO = new ElectronicSignBO();
        electronicSignBO.setAppId(appId);
        electronicSignBO.setSceneType(sceneType);
        HashMap<String, Object> param = new HashMap<>(1);
        param.put("userInfoList", params);
        electronicSignBO.setUserData(JSONUtil.parseObj(JSONUtil.toJsonStr(param)));
        String result = abilityClient.reSignFile(electronicSignBO, request.getHeader("ptToken"));
        return JSONUtil.parseObj(result).getStr("message");
    }

    @Override
    public List<OfferWorkerEditDTO> lessCodeEditInformation(List<OfferWorkerEditDTO> workerEditDTOList, Result<String> result) {
        StringBuilder message = new StringBuilder();
        List<OfferWorkerEditDTO> res = workerEditDTOList.stream().filter(w -> {
            TbOfferWorker worker = getById(w.getWorkerId());
            if (worker != null && OfferWorkerStatusEnum.lessCodeEditInformationNoException(worker.getWorkerStatus())) {
                return true;
            } else {
                message.append(w.getWorkerId()).append(" ");
                return false;
            }
        }).collect(Collectors.toList());
        if (message.length() > 0) {
            result.setMessage("以下预备员工[" + message + "]状态不支持更改信息");
        }
        return res;
    }

    @Override
    @Transactional
    public void approvalPlanReportDate(OfferWorkerEditDTO dto) {
        Date planReportDate = dto.getPlanReportDate();
        String approvalNote = dto.getApprovalNote();

        TbOfferWorker tbOfferWorker = getById(dto.getWorkerId());
        if (tbOfferWorker == null) {
            throw new AppBusinessException("找不到预备员工");
        }
        Date applyReportDate = tbOfferWorker.getApplyReportDate();
        if (applyReportDate == null) {
            throw new AppBusinessException("预备员工没有申请或申请已通过");
        }
        if ("社会招聘".equals(tbOfferWorker.getInType()) && !iTbWorkerExperienceService.checkJoinDateAndEndDate(tbOfferWorker.getWorkerId(), planReportDate)) {
            LambdaQueryWrapper<TbWorkerExperience> expWrapper = new LambdaQueryWrapper<>();
            expWrapper.eq(TbWorkerExperience::getWorkerId, tbOfferWorker.getWorkerId())
                    .orderByDesc(TbWorkerExperience::getEndDate)
                    .last("limit 1");
            TbWorkerExperience tbWorkerExperience = tbWorkerExperienceMapper.selectOne(expWrapper);
            Date endDate = tbWorkerExperience.getEndDate();
            throw new AppBusinessException("此计划入职日期早于预备员工"+tbOfferWorker.getWorkerId()+"的最后一次工作经历结束时间(" + DateUtil.format(endDate, "yyyy-MM-dd") + ")");
        }
        Date oldReportDate = tbOfferWorker.getPlanReportDate();


        UpdateWrapper<TbOfferWorker> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .set(TbOfferWorker::getPlanReportDate, planReportDate)
                .set(TbOfferWorker::getApplyReportDate, null)
                .set(TbOfferWorker::getApplyChangeReason, null)
                .eq(TbOfferWorker::getWorkerId, dto.getWorkerId());
        boolean update = update(updateWrapper);
        if (!update) {
            throw new AppBusinessException("更新失败");
        }

        String userId = commService.getLoginUserId();
        String userNameAndId = commService.getLoginUserNameAndId();
        approvalRecordService.saveRecord(dto.getWorkerId(), BusiEnumDefine.FLOW_STATUS_APPROVAL_PLAN_DATE, userId,
                userNameAndId, "您提交的修改入职日期申请已审批通过，您的计划入职日期将修改为：" + DateUtil.format(planReportDate, "yyyy-MM-dd")
                        + "，审核意见：" + approvalNote + "。请您按时报到，谢谢！", BusiEnumDefine.APPROVAL_APPROVE);

        SdEmailTemplate template = emailTemplateService.getById("APPROVAL_PLAN_REPORT_DATE");
        String templateTitle = template.getEmailTemplateTitle();
        String templateContent = template.getEmailTemplateContent();

        TbOfferWorker offerWorker = getById(dto.getWorkerId());
        String workerId = offerWorker.getWorkerId();
        String workerName = offerWorker.getWorkerName();
        String workerNameAndId = workerName + "/" + workerId;
        String deptNameChain = offerWorker.getDeptNameChain();
        String workCity = offerWorker.getWorkCity();

        Map<String, String> map = iSdDeptService.getBpAndContactorAndSSC(deptNameChain, workCity);

        List<SdNoticeRecord> list = new ArrayList<>();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        if (!map.isEmpty()) {
            int i = applyReportDate.compareTo(planReportDate);
            //您好，预备员工 {员工姓名/工号} 的计划报到日期已经修改为{最新入职日期}，请知悉。您可登录新员工系统关注预备员工最新动态。谢谢！newemployee.h3c.com
            templateContent = templateContent.replace("{员工姓名/工号}", workerNameAndId)
                    .replace("{最新入职日期}", simpleDateFormat.format(planReportDate));
            if (i == 0) {
                templateContent = templateContent.replace("修改", "确认");
            }
            SdNoticeRecord emailNoticeRecord = iSdNoticeRecordService.createEmailNoticeRecord("-1", map.get("ids"),
                    map.get("names"), map.get("emails"), templateTitle, templateContent, "");
            list.add(emailNoticeRecord);
        }
        //您好，您的计划报到日期修改为{最新入职日期}，请按新的计划报到日期按时报到，非常感谢！
        //如需再次变更计划入职日期，您可通过入职登记平台进行申请。
        SdEmailTemplate templateToWorker = emailTemplateService.getById("APPROVAL_PLAN_TO_WORKER");
        String toWorkerTitle = templateToWorker.getEmailTemplateTitle();
        String toWorkerContent = templateToWorker.getEmailTemplateContent();
        toWorkerContent = toWorkerContent.replace("{最新入职日期}", simpleDateFormat.format(planReportDate));
        SdNoticeRecord smsNoticeRecord = iSdNoticeRecordService.createSmsNoticeRecord(workerId, workerName,
                offerWorker.getPhoneNo(), toWorkerTitle, toWorkerContent);
        list.add(smsNoticeRecord);

        //日期变更通知主管
        //您好，您负责部门的{候选人}（手机号{手机号}）计划入职日期从{原日期}变更为{新日期}，您可点击链接进入系统查看该员工相关信息。
        SdEmailTemplate leaderTemplate = emailTemplateService.getById("MAIL_WHEN_REPORT_DATE");
        String leaderTitle = leaderTemplate.getEmailTemplateTitle();
        String leaderContent = leaderTemplate.getEmailTemplateContent();
        leaderTitle = leaderTitle.replace("{候选人}", tbOfferWorker.getWorkerName());
        leaderContent = leaderContent.replace("{候选人}",tbOfferWorker.getWorkerName())
                .replace("{手机号}", tbOfferWorker.getPhoneNo())
                .replace("{新日期}", simpleDateFormat.format(planReportDate) + "("+com.h3c.nem.utils.DateUtil.dateToWeek(planReportDate) + ")");
        if (oldReportDate == null) {
            leaderContent = leaderContent.replace("{原日期}", "暂无");
        } else {
            leaderContent = leaderContent.replace("{原日期}", simpleDateFormat.format(oldReportDate));
        }
        Map<String, String> leaderInfo = getLeaderInfo(tbOfferWorker);
        String leaderMail = leaderInfo.get("mail");
        if (!StringUtils.isEmpty(leaderMail)) {
            String leaderId = leaderInfo.get("id");
            String leaderName = leaderInfo.get("name");
            SdNoticeRecord mailRecord = iSdNoticeRecordService.createMailRecord(tbOfferWorker.getWorkerId(), leaderId, leaderName, leaderMail, leaderTitle, leaderContent);
            asyncSendMessage.sendMessage(Collections.singletonList(mailRecord));
        }
        asyncSendMessage.sendMessage(list);
    }

    private void setTable6(JCoTable table6, TbOfferWorker offerWorker) {
        List<String> countryCode = offerWorker.getForeignResidencyCountryCode();
        if (countryCode == null) {
            return;
        }
        if (countryCode.contains("US")) {
            //美国，给合规发邮件
//            邮件标题：员工涉外身份提醒！；邮件内容：“*** 部门新员工****** （工号、姓名），身份证号/护照号******：自我申报为美国人，请关注 ”；
            String complianceEmail = "H3C_Compliance@h3c.com";
            SdEmailTemplate template = emailTemplateService.getById("SEND_TO_COMPLIANCE_EMAIL");
            String templateTitle = template.getEmailTemplateTitle();
            String templateContent = template.getEmailTemplateContent();
            templateContent = templateContent.replace("{部门名称}", offerWorker.getDeptNameChain())
                    .replace("{员工姓名/工号}", offerWorker.getWorkerName() + "/" + offerWorker.getWorkerId())
                    .replace("{身份证号/护照号}", offerWorker.getCertNo());
            SdNoticeRecord sdNoticeRecord = iSdNoticeRecordService.createEmailNoticeRecord("-1", "", "合规公邮",
                    complianceEmail, templateTitle, templateContent, "");
            asyncSendMessage.sendMessage(Collections.singletonList(sdNoticeRecord));
        }
        countryCode.forEach(country -> {
            table6.appendRow();
            tableSetValue(table6, "ZJLQ", "1");
            tableSetValue(table6, "ZJLQGJ", country);
        });
    }

    private void setTable4(JCoTable table4, String workerId) {
        List<TbOfferLanguage> languageList = iTbOfferLanguageService.list(new LambdaQueryWrapper<TbOfferLanguage>()
                .eq(TbOfferLanguage::getWorkerId, workerId));
        int i = 2;
        for (TbOfferLanguage language : languageList) {
            table4.appendRow();
            tableSetValue(table4, "ZLAYZ", language.getLanguageType());
            tableSetValue(table4, "ZLAZS", language.getQualification());
            tableSetValue(table4, "ZLAHD", language.getGrantDate() == null ? "" : yyyyMMdd.format(language.getGrantDate()));
            String engMark = language.getEngMark();
            if (engMark.equals("1")) {
                tableSetValue(table4, "ZLAPX", "01");
            } else {
                tableSetValue(table4, "ZLAPX", "0" + i);
            }
            i++;
        }
    }

    private void setTable3(JCoTable table3, String workerId) {
        List<TbWorkerExperience> workList = workerExperienceService.list(new LambdaQueryWrapper<TbWorkerExperience>()
                .eq(TbWorkerExperience::getWorkerId, workerId));
        workList.forEach(work -> {
            table3.appendRow();
            tableSetValue(table3, "BEGDA", work.getBeginDate() == null ? "" : yyyyMMdd.format(work.getBeginDate()));
            tableSetValue(table3, "ENDDA", work.getEndDate() == null ? "" : yyyyMMdd.format(work.getEndDate()));
            tableSetValue(table3, "ZEMPL", work.getWorkPlace());
            tableSetValue(table3, "ZDEPT", work.getDepartment());
            tableSetValue(table3, "ZJTTL", work.getPost());
            tableSetValue(table3, "ZRESN", work.getLeaveReason());
            tableSetValue(table3, "ZREFE", work.getReferenceName());
            tableSetValue(table3, "ZRCON", work.getReferenceNameContact());
        });
    }

    private void setTable2(JCoTable table2, String workerId) {
        List<TbOfferStudy> studyList = studyService.list(new LambdaQueryWrapper<TbOfferStudy>().eq(TbOfferStudy::getWorkerId, workerId));
        studyList.forEach(study -> {
            table2.appendRow();
            tableSetValue(table2, "INSTI", study.getCollegeName());
            tableSetValue(table2, "FACH3", study.getMajorName());
            tableSetValue(table2, "BEGDA", study.getBeginDate() == null ? "" : yyyyMMdd.format(study.getBeginDate()));
            tableSetValue(table2, "ENDDA", study.getEndDate() == null ? "" : yyyyMMdd.format(study.getEndDate()));
            tableSetValue(table2, "INSMO", study.getStudyType() == null ? "" : study.getStudyType().getCode());
            tableSetValue(table2, "SLART", study.getEducation().getCode());
            tableSetValue(table2, "SLABS", study.getDegree().getCode());
            tableSetValue(table2, "ACACD", study.getGrantDate() == null ? "" : yyyyMMdd.format(study.getGrantDate()));
            tableSetValue(table2, "ACQID", study.getEducationNo());
            tableSetValue(table2, "ACCID", study.getDegreeNo());
            tableSetValue(table2, "ACAQM", study.getIsHighestEducation() ? "X" : "");
            tableSetValue(table2, "ACACM", study.getIsHighestDegree() ? "X" : "");
            tableSetValue(table2, "BFWKQ", study.getIsFirstStudy() ? "X" : "");
            tableSetValue(table2, "ZFACH3", study.getMajorName2());
            String collegeName = study.getCollegeName();
            List<TbSchool> schools = tbSchoolMapper.selectList(new LambdaQueryWrapper<TbSchool>().eq(TbSchool::getSchoolName, collegeName));
            if (!schools.isEmpty()) {
                TbSchool tbSchool = schools.get(0);
                tableSetValue(table2, "Z211", tbSchool.getFlag211() == 1 ? "X" : "");
                tableSetValue(table2, "Z985", tbSchool.getFlag985() == 1 ? "X" : "");
                tableSetValue(table2, "ZSYL", tbSchool.getFlagSyl() == 1 ? "X" : "");
            } else {
                tableSetValue(table2, "Z211", "");
                tableSetValue(table2, "Z985", "");
                tableSetValue(table2, "ZSYL", "");
            }
        });
    }

    private void setTable1(JCoTable inputTable, String workerId) {
        List<TbOfferFamily> familyList = familyService.list(new LambdaQueryWrapper<TbOfferFamily>()
                .eq(TbOfferFamily::getWorkerId, workerId));
        List<TbOfferContactor> contactorList = contactorService.list(new LambdaQueryWrapper<TbOfferContactor>()
                .eq(TbOfferContactor::getWorkerId, workerId));
        //家庭成员
        familyList.forEach(family -> {
            inputTable.appendRow();
            tableSetValue(inputTable, "FAMSA", family.getRelationType()); //成员关系
            tableSetValue(inputTable, "FANAM", family.getMemberName());
            tableSetValue(inputTable, "STRAS", family.getMemberAddress());
            tableSetValue(inputTable, "TELNR", family.getMemberPhone());
            tableSetValue(inputTable, "FGBOT", family.getWorkPlace());
        });
        //紧急联系人
        contactorList.forEach(contactor -> {
            inputTable.appendRow();
            tableSetValue(inputTable, "FAMSA", "99"); //成员关系: 紧急联系人
            tableSetValue(inputTable, "FANAM", contactor.getContactorName());
            tableSetValue(inputTable, "STRAS", contactor.getContactorAddress());
            tableSetValue(inputTable, "TELNR", contactor.getContactorPhone());
            tableSetValue(inputTable, "FGBOT", "");
        });
    }

    private void tableSetValue(JCoTable inputTable, String key, String value) {
        log.info("sap请求日志: key=" + key + ", value=" + value);
        inputTable.setValue(key, value);
    }

    private void setObject(JCoParameterList importParameter, TbOfferWorker offerWorker) {
        log.info("sap请求日志: setObject={}", offerWorker);
        JCoStructure lwData = importParameter.getStructure("LW_DATA");
        lwData.setValue("NACHN", offerWorker.getWorkerName());
        lwData.setValue("VORNA", ""); //名 目前传空
        lwData.setValue("NAME2", offerWorker.getOldName());

//        String nationCode = EnumUtil.getEnumValue("NEW_STAFF_ETHNICITY", offerWorker.getNation());
        lwData.setValue("RACKY", offerWorker.getNation()); //民族编码  表中已存编码
        lwData.setValue("GBDAT", offerWorker.getBirthday());
        lwData.setValue("GESCH", offerWorker.getSex().equals("男") ? "1" : "2");

//        String staffOrigin = EnumUtil.getEnumValue("NEW_STAFF_ORIGIN", offerWorker.getNationPlace());
        lwData.setValue("GBORT", EnumUtil.getNationPlaceName(offerWorker.getNationPlace())); //籍贯编码  表中已存编码  2022/10/10 籍贯进SAP传文字

//        String newStaffPolitics = EnumUtil.getEnumValue("NEW_STAFF_POLITICS", offerWorker.getPoliticalLandscape());
        lwData.setValue("PCODE", offerWorker.getPoliticalLandscape()); //政治面貌编码 表中已存编码
        lwData.setValue("ICNUM", offerWorker.getCertNo());
        lwData.setValue("NATIO", offerWorker.getNationalityCode());
        lwData.setValue("ZHUKOT", offerWorker.getHouseHoldCode());
        lwData.setValue("NAMEDA", offerWorker.getArchiveOrg());
        lwData.setValue("ORT01", offerWorker.getHouseHoldCity());
        lwData.setValue("RUFNM", offerWorker.getInType().contains("校招") ? "应届毕业生" : "社会招聘");//社招的应届生进SAP是社招，在入职登记算应届
        lwData.setValue("FAMST", offerWorker.getSpouseFlag());
        lwData.setValue("FAMDT", offerWorker.getMarriageDate() == null ? "" : yyyyMMdd.format(offerWorker.getMarriageDate()));
        lwData.setValue("DAT02", ""); //特殊工龄工作时间
        lwData.setValue("DAT03", offerWorker.getInType().contains("应届毕业生") ? yyyyMMdd.format(offerWorker.getContractBeginDate()) : yyyyMMdd.format(offerWorker.getFirstWorkDate()));//社招的应届生按应届生走，社会工龄计算以入职时间为开始时间
        lwData.setValue("SCHKZ", offerWorker.getWorkOrder());
        lwData.setValue("ZTERF", offerWorker.getSignInFlag());
        lwData.setValue("WWEEK", offerWorker.getFlexibleFlag());
        lwData.setValue("ZDATE", offerWorker.getContractBeginDate() == null ? "" : yyyyMMdd.format(offerWorker.getContractBeginDate()));
        lwData.setValue("KZTIM", offerWorker.getCheckWorkType());
        lwData.setValue("USRID", offerWorker.getPhoneNo()); //通讯标识 即手机号
        lwData.setValue("ZJYRYY", offerWorker.getNeedSignCompetition());
        lwData.setValue("ZJYRYX", offerWorker.getCompetitionSignFlag());
        lwData.setValue("ZJYQX", offerWorker.getCompetitionPeriod());
        lwData.setValue("ZJYGS", offerWorker.getCompetitionCompany());
        lwData.setValue("ZJYQSSJ", offerWorker.getCompetitionSignDate() == null ? "" : yyyyMMdd.format(offerWorker.getCompetitionSignDate()));
        lwData.setValue("ZJYBCBZ", offerWorker.getCompetitionRewardStandard());
        lwData.setValue("LOCAT", offerWorker.getContactAddress());
        lwData.setValue("ZJOIN", offerWorker.getAddPartyDate() == null ? "" : yyyyMMdd.format(offerWorker.getAddPartyDate()));
        lwData.setValue("PRBZT", offerWorker.getProbationMonth());
        lwData.setValue("PRBEH", "012");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String approvalOfferWorkerData(String workerId, String approvalNote, Integer approvalType, String copyEmail, String sendMailFlag) {
        //BusiEnumDefine.NOTICE_MAIL_SEND_NO.equals(sendMailFlag) 即定时任务开始超6个月取消报道
        if (BusiEnumDefine.NOTICE_MAIL_SEND_YES.equals(sendMailFlag)) {
            boolean haveAuth =  commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_ADMIN)
                    || commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_NEW_WORKER_BP)
                    || commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_OFFER_BP)
                    || commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_OFFER_SSC_MANAGER)
                    || commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_OFFER_DEPT_MANAGER);
            if (!haveAuth) {
                throw new AppBusinessException(StatusCodeEnum.UN_AUTH.getMassage());
            }
        }

        TbOfferWorker worker = new TbOfferWorker();
        worker.setWorkerId(workerId);
        if (approvalType == 1) {
            checkApprovalStatus(workerId);
            worker.setWorkerStatus(OfferWorkerStatusEnum.待签合同);
            checkWorkerStudy(workerId);
        } else if (approvalType == 2) {
            checkApprovalStatus(workerId);
            worker.setWorkerStatus(OfferWorkerStatusEnum.待补充资料);
        } else {
            checkWorkerStatus(workerId);
            worker.setWorkerStatus(OfferWorkerStatusEnum.取消入职);
        }
        updateById(worker);
        String userId = commService.getLoginUserIdWithNoException();
        String userName = commService.getLoginUserNameWithNoException();
        approvalRecordService.saveRecord(workerId, BusiEnumDefine.FLOW_STATUS_OFFER_WORKER, userId,
                userName + "/" + userId, approvalNote, approvalType);

        //发邮件
        List<SdNoticeRecord> sdNoticeRecord = iSdNoticeRecordService.createOfferWorkerApproval(getById(workerId), approvalNote, approvalType, sendMailFlag);
        asyncSendMessage.sendMessage(sdNoticeRecord);
        return "SUCCESS";
    }

    public void checkWorkerStudy(String workerId) {
        TbOfferWorker offerWorker = lambdaQuery().eq(TbOfferWorker::getWorkerId, workerId).one();
        Date reportDate = offerWorker.getPlanReportDate();
        if (reportDate == null) {
            throw new AppBusinessException("预备员工" + workerId + "没有计划入职日期");
        }
        if (offerWorker.getLastLeaveDate() != null && reportDate.compareTo(offerWorker.getLastLeaveDate()) <= 0) {
            throw new AppBusinessException("预备员工" + workerId + "的计划入职日期早于他的上家公司离职日期");
        }
        LambdaQueryWrapper<TbOfferStudy> studyWrapper = new LambdaQueryWrapper<TbOfferStudy>()
                .eq(TbOfferStudy::getWorkerId, workerId)
                .orderByDesc(TbOfferStudy::getEndDate);
        List<TbOfferStudy> studyList = tbOfferStudyMapper.selectList(studyWrapper);
        studyList.forEach(s -> {
            Date beginDate = s.getBeginDate();
            Date endDate = s.getEndDate();
            if (beginDate == null) {
                throw new AppBusinessException("预备员工" + workerId + "的 " + s.getCollegeName() + " 学历信息没有开始时间");
            }
            if (endDate == null) {
                throw new AppBusinessException("预备员工" + workerId + "的 " + s.getCollegeName() + " 学历信息没有毕业时间");
            }
            if(DateUtil.toLocalDateTime(beginDate).plusMonths(3).compareTo(DateUtil.toLocalDateTime(endDate)) > 0) {
                throw new AppBusinessException("预备员工" + workerId + "的 " + s.getCollegeName() + " 学历信息学习时长少于3个月");
            }
            if (endDate.compareTo(reportDate) >= 0) {
                throw new AppBusinessException("预备员工" + workerId + "的 " + s.getCollegeName() + " 学历信息毕业时间晚于计划入职时间");
            }
        });

    }

    public void sscUpdatePlanReportDate(OfferWorkerEditDTO editDTO) {
        boolean haveAuth = commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_OFFER_SSC_MANAGER)
                || commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_OFFER_DEPT_MANAGER)
                || commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_ADMIN);

        if (!haveAuth) {
            throw new AppBusinessException("仅SSC可随时更新员工计划入职日期");
        }

        Date planReportDate = editDTO.getPlanReportDate();
        String workerId = editDTO.getWorkerId();
        TbOfferWorker worker = getById(workerId);
        boolean sendFlag = false;

        if (worker != null && !Objects.equals(planReportDate, worker.getPlanReportDate())){
            sendFlag = true;
            lambdaUpdate().eq(TbOfferWorker::getWorkerId, workerId).set(TbOfferWorker::getPlanReportDate, planReportDate).update();
        }
        if (sendFlag) {
            String loginUserIdAndName = commService.getLoginUserIdAndName();
            SdEmailTemplate updatePlanDateSmsTemplate = emailTemplateService.getById("UPDATE_PLAN_DATE_SMS");
            String title = updatePlanDateSmsTemplate.getEmailTemplateTitle();
            String content = updatePlanDateSmsTemplate.getEmailTemplateContent();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String planStr = dateFormat.format(planReportDate);
            //您好，招聘接口人将您的计划报到日期修改为 2022-06-21，请按新的计划报到日期按时报到，非常感谢！如需变更可通过入职登记平台进行申请。
            content = content.replace("{计划入职日期}", planStr);
            SdNoticeRecord smsNoticeRecord = iSdNoticeRecordService.createSmsNoticeRecord(worker.getWorkerId(),
                    worker.getWorkerName(), worker.getPhoneNo(), title, content);

            //您好，预备员工 张三/92363365 的计划报到日期已经被修改为 2022-06-21，请知悉。您可登录新员工系统关注预备员工最新动态。谢谢！
            //newemployee.h3c.com
            SdEmailTemplate updatePlanDateEmailTemplate = emailTemplateService.getById("UPDATE_PLAN_DATE_EMAIL");
            String emailTitle = updatePlanDateEmailTemplate.getEmailTemplateTitle();
            String emailContent = updatePlanDateEmailTemplate.getEmailTemplateContent();
            emailContent = emailContent.replace("{员工姓名/工号}", worker.getWorkerId() + "/" + worker.getWorkerName())
                    .replace("{操作人}", loginUserIdAndName)
                    .replace("{计划入职日期}", planStr);

            Map<String, String> map = iSdDeptService.getBpAndContactorAndSSC(worker.getDeptNameChain(), worker.getWorkCity());
            if (!map.isEmpty()) {
                SdNoticeRecord emailNoticeRecord = iSdNoticeRecordService.createEmailNoticeRecord("-1", map.get("ids"),
                        map.get("names"), map.get("emails"), emailTitle, emailContent, "");
                asyncSendMessage.sendMessage(Arrays.asList(smsNoticeRecord, emailNoticeRecord));
            }
        }
    }


    private void checkWorkerStatus(String workerId) {
        TbOfferWorker offerWorker = getById(workerId);
        OfferWorkerStatusEnum.lessCode(offerWorker.getWorkerStatus());
    }

    private void checkApprovalStatus(String workerId) {
        TbOfferWorker offerWorker = getById(workerId);
        OfferWorkerStatusEnum workerStatus = offerWorker.getWorkerStatus();
        if (!OfferWorkerStatusEnum.待审核入职资料.equals(workerStatus)) {
            throw new AppBusinessException("预备员工当前状态不支持审核");
        }
    }

    @Override
    public String batchApprovalOfferWorkerData(String workerIds, String approvalNote, Integer approvalType, String copyEmail) {
        List<String> list = Arrays.asList(workerIds.split(","));
        StringBuilder idBuilder = new StringBuilder();
        list.forEach(id -> {
            try {
                iTbOfferWorkerService.approvalOfferWorkerData(id, approvalNote, approvalType, copyEmail, BusiEnumDefine.NOTICE_MAIL_SEND_YES);
            } catch (Exception e) {
                if (e instanceof AppBusinessException) {
                    idBuilder.append("\n").append(id).append(" ").append(e.getMessage());
                } else {
                    log.error(id);
                    e.printStackTrace();
                    idBuilder.append("\n").append(id);
                }
            }
        });
        if (StringUtils.isBlank(idBuilder.toString())) {
            return "SUCCESS";
        } else {
            return "以下预备员工批量处理失败：" + idBuilder;
        }
    }

    private List<String> judgeIfFillFinish(Boolean needAddInfo, String inType) {
        ArrayList noFillList = new ArrayList<>();
        String userId = CommonUtil.getActivUser().getUserId();
        List<TbOfferAttachment> attachments = attachmentService.list(new QueryWrapper<TbOfferAttachment>().lambda()
                .eq(TbOfferAttachment::getWorkerId, userId)
                .eq(TbOfferAttachment::getAlreadySave, true)
        );
        if (attachments.size() == 0) {
            throw new BusinessException(400, "附件信息未保存，请先完善并保存信息");
        }
        List<Integer> typeList = attachments.stream().map(TbOfferAttachment::getFileType).collect(Collectors.toList());
        if (needAddInfo) {
            if (!typeList.contains(TbOfferAttachment.RESIGN_CERT) && !StringUtils.isEmpty(inType) && !inType.contains("应届毕业生")) {
                throw new BusinessException(400, "请补充离职证明后再提交");
            }
        }
        int familyCount = familyService.count(new QueryWrapper<TbOfferFamily>().lambda()
                .eq(TbOfferFamily::getWorkerId, userId)
                .eq(TbOfferFamily::getAlreadySave, true)
        );
        if (familyCount == 0) {
            throw new BusinessException(400, "家庭信息未保存，请先完善并保存信息");
        }
        int contactorCount = contactorService.count(new QueryWrapper<TbOfferContactor>().lambda()
                .eq(TbOfferContactor::getWorkerId, userId)
                .eq(TbOfferContactor::getAlreadySave, true)
        );
        if (contactorCount == 0) {
            throw new BusinessException(400, "紧急联系人信息未保存，请先完善并保存信息");
        }
        int studyCount = studyService.count(new QueryWrapper<TbOfferStudy>().lambda()
                .eq(TbOfferStudy::getWorkerId, userId)
                .eq(TbOfferStudy::getAlreadySave, true)
        );
        if (studyCount == 0) {
            throw new BusinessException(400, "学历信息未保存，请先完善并保存信息");
        }
        int workerExCount = workerExperienceService.count(new QueryWrapper<TbWorkerExperience>().lambda()
                .eq(TbWorkerExperience::getWorkerId, userId)
                .eq(TbWorkerExperience::getAlreadySave, true)
        );
        if (!StringUtils.isEmpty(inType) && !inType.contains("应届毕业生") && workerExCount == 0) {
            throw new BusinessException(400, "工作经历信息未保存，请先完善并保存信息");
        }
        if (!typeList.contains(TbOfferAttachment.RESIGN_CERT)) {
            if (!(org.springframework.util.StringUtils.hasText(inType) && inType.contains("应届毕业生"))) {
                noFillList.add("离职证明");
            }
        }
        if (!typeList.contains(TbOfferAttachment.MEDICAL_REPORT)) {
            if (!(org.springframework.util.StringUtils.hasText(inType) && inType.contains("应届毕业生(校招)"))) {
                noFillList.add("体检证明");
            }
        }
        return noFillList;
    }

    @Override
    public List<TbOfferWorkerDTO> getOfferWorkerBp(TbOfferWorkerDTO dto, String startDate, String endDate, Boolean isBp) {
        PageInfo<TbOfferWorkerDTO> workerBp = getOfferWorkerBp(dto, startDate, endDate, isBp, null, null);
        return workerBp.getList();
    }

    @Override
    public PageInfo<TbOfferWorkerDTO> getOfferWorkerBp(TbOfferWorkerDTO dto, String startDate, String endDate, Boolean isBp,
                                                       Integer currentPage, Integer pageSize) {
        LambdaQueryWrapper<TbOfferWorker> queryWrapper = new QueryWrapper<TbOfferWorker>().lambda();

        if (!commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_ADMIN)
                && !commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_SS_MANAGER)
                && !commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_RECRUITMENT)) {
            checkUserRoleOfManageDept(isBp, queryWrapper);
        }

        if (StringUtils.isNotBlank(dto.getDeptNameChain())) {
            queryWrapper.likeRight(TbOfferWorker::getDeptNameChain, dto.getDeptNameChain());
        }
        if (StringUtils.isNotBlank(dto.getWorkerId())) {
            queryWrapper.eq(TbOfferWorker::getWorkerId, dto.getWorkerId());
        }
        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            try {
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                Date startTime = dateFormat.parse(startDate);
                Date endTime = dateFormat.parse(endDate);
                queryWrapper.ge(TbOfferWorker::getPlanReportDate, startTime);
                queryWrapper.le(TbOfferWorker::getPlanReportDate, endTime);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        String joinDateStart = dto.getJoinDateStart();
        String joinDateEnd = dto.getJoinDateEnd();
        if (StringUtils.isNotBlank(joinDateStart) && StringUtils.isNotBlank(joinDateEnd)) {
            try {
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                Date startTime = dateFormat.parse(joinDateStart);
                Date endTime = dateFormat.parse(joinDateEnd);
                queryWrapper.ge(TbOfferWorker::getJoinDate, startTime);
                queryWrapper.le(TbOfferWorker::getJoinDate, endTime);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        if (dto.getApplyChange() != null && dto.getApplyChange() == 1) {
            queryWrapper.isNotNull(TbOfferWorker::getApplyReportDate);
        }
        if (StringUtils.isNotBlank(dto.getTeacherInfo())) {
            queryWrapper.like(TbOfferWorker::getTeacherInfo, dto.getTeacherInfo());
        }
        if (StringUtils.isNotBlank(dto.getDirectManager())) {
            queryWrapper.like(TbOfferWorker::getDirectManager, dto.getDirectManager());
        }
        String workerStatusList = dto.getWorkerStatusList();
        if (StringUtils.isNotBlank(workerStatusList)) {
            List<Integer> status = Stream.of(workerStatusList.split(",")).map(Integer::valueOf).collect(Collectors.toList());
            queryWrapper.in(TbOfferWorker::getWorkerStatus, OfferWorkerStatusEnum.valueOfKey(status));
        }
        if (StringUtils.isNotBlank(dto.getDataSource())) {
            queryWrapper.eq(TbOfferWorker::getDataSource, dto.getDataSource());
        }
        if (StringUtils.isNotBlank(dto.getInType())) {
            queryWrapper.eq(TbOfferWorker::getInType, dto.getInType());
        }
        if (dto.getOfferStatusCode() != null) {
            queryWrapper.eq(TbOfferWorker::getOfferStatus, OfferWorkerOfferStatusEnum.valueOfKey(dto.getOfferStatusCode()));
        }
        if (StringUtils.isNotBlank(dto.getPersonnelRange())) {
            queryWrapper.eq(TbOfferWorker::getPersonnelRange, dto.getPersonnelRange());
        }
        queryWrapper.orderByDesc(TbOfferWorker::getWorkerId);
        Page<TbOfferWorkerDTO> page;
        if (currentPage != null && pageSize != null) {
            page = PageHelper.startPage(currentPage, pageSize);
        } else {
            page = new Page<>();
        }
        List<TbOfferWorker> list = list(queryWrapper);
        List<TbOfferWorkerDTO> tbOfferWorkerDTOS = TbOfferWorkerMapstruct.INSTANCE.entityToDto(list);
        List<String> personnelCode = tbOfferWorkerDTOS.stream().map(TbOfferWorkerDTO::getPersonnelRangeCode)
                .collect(Collectors.toList());
        Map<String, String> middleMap = personnelRegisterMiddleService.getCompanyNameByPersonnelCodeList(personnelCode);
        List<String> idList = tbOfferWorkerDTOS.stream().map(TbOfferWorkerDTO::getWorkerId).collect(Collectors.toList());
        Map<String, String> fileIdList = attachmentService
                .getOfferWorkerFileIdList(AttachmentFileTypeEnum.WORK_CARD.getCode(), idList);
        tbOfferWorkerDTOS.forEach(d -> {
            if (Objects.isNull(d.getProbationMonth()) || d.getProbationMonth() == 0) {
                d.setTypeOfTrialPeriod("A");
            } else {
                d.setTypeOfTrialPeriod("B");
            }
            d.setCompanyName(middleMap.get(d.getPersonnelRangeCode()));
            d.setWorkerCardFileId(fileIdList.get(d.getWorkerId()));
        });
        PageInfo<TbOfferWorkerDTO> pageInfo = page.toPageInfo();
        pageInfo.setList(tbOfferWorkerDTOS);
        return pageInfo;
    }

    /**
     * 校验用户角色管理的部门
     *
     * @param isBp         页面
     * @param queryWrapper 拼接sql
     */
    @SafeVarargs
    private final void checkUserRoleOfManageDept(Boolean isBp, LambdaQueryWrapper<TbOfferWorker>... queryWrapper) {
        String loginUserRole = commService.getLoginUserRole();
        List<String> nameChainList = new ArrayList<>();
        List<String> workerId = new ArrayList<>();
        if (isBp) {
            if (loginUserRole.contains(String.valueOf(BusiEnumDefine.USER_ROLE_OFFER_BP))
                    || loginUserRole.contains(String.valueOf(BusiEnumDefine.USER_ROLE_NEW_WORKER_BP))) {
                nameChainList = iSdDeptService.getBpManageDeptNameChainList(SdDept::getBpUserId);
            } else if (commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_DEPT_CONTACTOR)) {
                nameChainList = iSdDeptService.getBpManageDeptNameChainList(SdDept::getContactorId);
            } else if (commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_DEPT_MANAGER) || commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_DIRECT_MANAGER)) {
                if (commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_DIRECT_MANAGER)) {
                    workerId = tbOfferWorkerMapper.queryWorkerOfManager(commService.getLoginUserId());
                }
                if (commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_DEPT_MANAGER)) {
                    nameChainList = iSdDeptService.getBpManageDeptNameChainList(SdDept::getDeptManagerId);
                }
                if (CollectionUtils.isEmpty(workerId) && CollectionUtils.isEmpty(nameChainList)) {
                    throw new AppBusinessException("名下没有管理的部门");
                }
            } else {
                throw new AppBusinessException("没有权限");
            }
        } else {
            if (loginUserRole.contains(String.valueOf(BusiEnumDefine.USER_ROLE_OFFER_DEPT_MANAGER))) {
                nameChainList = iSdDeptService.getBpManageDeptNameChainList(SdDept::getOfferDeptManagerId);
            } else if (loginUserRole.contains(String.valueOf(BusiEnumDefine.USER_ROLE_OFFER_SSC_MANAGER))) {
                return; //全部部门
            } else {
                throw new AppBusinessException("没有权限");
            }
        }
        if (nameChainList.isEmpty() && !(commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_DEPT_MANAGER) || commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_DIRECT_MANAGER))) {
            throw new AppBusinessException("没有管理的部门");
        }
        for (LambdaQueryWrapper<TbOfferWorker> wrapper : queryWrapper) {
            List<String> finalNameChainList = nameChainList;
            List<String> finalWorkerId = workerId;
            wrapper.and(wrap-> wrap.in(!CollectionUtils.isEmpty(finalNameChainList),TbOfferWorker::getDeptNameChain, finalNameChainList).or(!CollectionUtils.isEmpty(finalNameChainList)).in(!CollectionUtils.isEmpty(finalWorkerId),TbOfferWorker::getWorkerId, finalWorkerId));
        }
    }

    @Override
    public List<TbOfferWorker> searchWorker(String keyword) {
        LambdaQueryWrapper<TbOfferWorker> queryWrapper = new QueryWrapper<TbOfferWorker>().lambda();
        queryWrapper.select(TbOfferWorker::getWorkerId, TbOfferWorker::getWorkerName);
        int i = CommonUtil.judgeStr(keyword);
        if (i == 1) {
            queryWrapper.like(TbOfferWorker::getWorkerId, keyword);
        } else if (i == 2) {
            queryWrapper.like(TbOfferWorker::getNamePinyin, keyword);
        } else if (i == 3) {
            queryWrapper.like(TbOfferWorker::getWorkerName, keyword);
        } else {
            return null;
        }
        queryWrapper.orderByAsc(TbOfferWorker::getWorkerId);
        return list(queryWrapper);
    }

    @Override
    public List<JSONObject> getWorkerStatusCount(Boolean isBp) {
        LambdaQueryWrapper<TbOfferWorker> pendingQw = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<TbOfferWorker> joinedQw = new LambdaQueryWrapper<>();
        if (!commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_ADMIN)
                && !commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_SS_MANAGER)
                && !commService.checkLoginUserRole(BusiEnumDefine.USER_ROLE_RECRUITMENT)) {
            checkUserRoleOfManageDept(isBp, pendingQw, joinedQw);
        }
        List<TbOfferWorker> list = list(pendingQw);
        Map<String, Integer> nameMap = list.stream()
                .collect(Collectors.groupingBy(o -> OfferWorkerStatusEnum.getNameByCode(o.getWorkerStatus()),
                        Collectors.collectingAndThen(Collectors.toList(), List::size)));
        List<JSONObject> result = new ArrayList<>();
        result.add(getJSONObject(nameMap, OfferWorkerStatusEnum.待填写入职资料.getName(), "待填写入职资料"));
        result.add(getJSONObject(nameMap, OfferWorkerStatusEnum.待补充资料.getName(), "待补充资料"));
        result.add(getJSONObject(nameMap, OfferWorkerStatusEnum.待审核入职资料.getName(), "待审核资料人数"));

        long applyChangeCount = list.stream().filter(o -> o.getApplyReportDate() != null).count();
        JSONObject jsonObject3 = new JSONObject();
        jsonObject3.put("title", "申请变更入职日期");
        jsonObject3.put("num", applyChangeCount);
        result.add(jsonObject3);

        //2022/8/3 本周待签合同/合同签署中  -->  全部待签合同/合同签署中
//        pendingQw.ge(TbOfferWorker::getPlanReportDate, new Date())
//                .le(TbOfferWorker::getPlanReportDate, com.h3c.nem.utils.DateUtil.getLastDayOfWeek(new Date()));
        List<TbOfferWorker> thisWeek = list(pendingQw);
        long pendingCount = thisWeek.stream().filter(o -> Objects.equals(o.getWorkerStatus(), OfferWorkerStatusEnum.待签合同)).count();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("title", "待签合同");
        jsonObject.put("num", pendingCount);
        result.add(jsonObject);
        long beingSignedCount = thisWeek.stream().filter(o -> Objects.equals(o.getWorkerStatus(), OfferWorkerStatusEnum.合同签署中)).count();
        JSONObject beingSigned = new JSONObject();
        beingSigned.put("title", "合同签署中");
        beingSigned.put("num", beingSignedCount);
        result.add(beingSigned);

        joinedQw.ge(TbOfferWorker::getJoinDate, com.h3c.nem.utils.DateUtil.getLastDayOfMonth(new Date()))
                .le(TbOfferWorker::getJoinDate, new Date())
                .eq(TbOfferWorker::getWorkerStatus, OfferWorkerStatusEnum.已入职);
        int joinCount = count(joinedQw);
        JSONObject jsonObject2 = new JSONObject();
        jsonObject2.put("title", "本月已入职人数");
        jsonObject2.put("num", joinCount);
        result.add(jsonObject2);
        return result;
    }

    public JSONObject getJSONObject(Map<String, Integer> nameMap, String key, String name) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("title", name);
        jsonObject.put("num", nameMap.get(key) == null ? 0 : nameMap.get(key));
        return jsonObject;
    }

    @Override
    public Map<String, Object> getWorkerDetail(String workerId) {
        Map<String, Object> res = new HashMap<>();
        TbOfferWorker offerWorker = getById(workerId);
        TbOfferWorkerDTO dto = JSONObject.parseObject(JSON.toJSONString(offerWorker), TbOfferWorkerDTO.class);
        String nameChain = dto.getDeptNameChain();
        SdDept dept = iSdDeptService.getDeptByNameChain(nameChain);
        String deptType = dept.getDeptType();
        if (Objects.equals(deptType, "RD")) {
            dto.setIsResearch(1);
        } else {
            dto.setIsResearch(0);
        }
        res.put("offerWorker", dto);

        List<TbOfferAttachmentVO> offerAttachment = attachmentService.getOfferAttachment(null, workerId);
        res.put("offerAttachment", offerAttachment);

        List<TbOfferFamilyVO> familyList = familyService.getFamilyByWorkerId(workerId);
        res.put("familyList", familyList);

        List<TbOfferContactorVO> contactorList = contactorService.getContactorList(workerId);
        res.put("contactorList", contactorList);

        List<TbOfferStudyVO> offerStudyList = studyService.getStudyInfoByWorkerId(workerId);
        res.put("offerStudyList", offerStudyList);

        List<TbWorkerExperienceVO> workerExperienceList = workerExperienceService.getWorkExperienceByWorkerId(workerId);
        res.put("workerExperienceList", workerExperienceList);

        List<TbOfferPatent> offerPatentList = iTbOfferPatentService.getOfferPatentInfoByWorkerId(workerId);
        res.put("offerPatentList", offerPatentList);

        List<TbOfferArchieve> offerArchieveList = iTbOfferArchieveService.getOfferArchieveByWorkerId(workerId);
        res.put("offerArchieveList", offerArchieveList);

        List<TbApprovalRecordDTO> recordList = approvalRecordService.getApprovalRecordList(workerId);
        res.put("approvalRecordList", recordList);

        List<TbOfferLanguage> offerLanguageList =  iTbOfferLanguageService.getOfferLanguageByWorkerId(workerId);
        res.put("offerLanguageList", offerLanguageList);

        return res;
    }

    /**
     * offer调整信息审核
     *
     * @param offerAdjustDTO offer调整信息
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String submitOfferAdjust(OfferAdjustDTO offerAdjustDTO) {
        String workerId = offerAdjustDTO.getWorkerId();
        String postModifyType = offerAdjustDTO.getPostModifyType();
        String personnelRange = offerAdjustDTO.getPersonnelRange();
        String personnelRangeCode = offerAdjustDTO.getPersonnelRangeCode();
        String subPersonnelRange = offerAdjustDTO.getSubPersonnelRange();
        String subPersonnelRangeCode = offerAdjustDTO.getSubPersonnelRangeCode();
        String deptNameChain = offerAdjustDTO.getDeptNameChain();
        String postName = offerAdjustDTO.getPostName();
        String postId = offerAdjustDTO.getPostId();
        String workCity = offerAdjustDTO.getWorkCity();
        String outerCity = offerAdjustDTO.getOuterCity();

        if (iTbOfferModifyService.checkOfferModifyHavingApproving(workerId)) {
            throw new AppBusinessException("该预备员工存在正在审核的offer修改单");
        }

        TbOfferWorker offerWorker = getById(workerId);
        if (offerWorker == null) {
            throw new AppBusinessException("找不到预备员工");
        }

        //保存变更记录
        String flowId = iTbOfferModifyService.saveOfferModify(offerAdjustDTO, offerWorker);

        if ("1".equals(postModifyType)) {
            if (StringUtils.isEmpty(deptNameChain)) {
                throw new AppBusinessException("员工当前无所属部门，无法发起审批");
            } else {
                SdDept deptByNameChain = iSdDeptService.getDeptByNameChain(deptNameChain);
                if (deptByNameChain == null) {
                    throw new AppBusinessException("当前员工所属部门不存在，无法发起审批");
                }
            }
            //发待办 发邮件 最开始给干部部长发
            SdNoticeRecord sdNoticeRecord = iSdNoticeRecordService.createOfferModifyRecord(flowId, deptNameChain, "APPROVAL_OFFER_EMAIL", 51);
            String userId = commService.getLoginUserId();
            String name = commService.getLoginUserNameWithNoException();
            SdTodoTask todoTask = iSdTodoTaskService.createOfferModifyTodoTask(sdNoticeRecord.getTargetId(),
                    OfferModifyApprovalEnum.OFFER_MODIFY_BP_SUBMIT, flowId, "N7", "预备员工offer信息修改审核", userId, name);
            asyncSendMessage.sendMessage(Collections.singletonList(sdNoticeRecord));
            asyncSendMessage.onlySendTodoTask(Collections.singletonList(todoTask), false);
        } else {
            TbOfferWorker worker = new TbOfferWorker();
            worker.setDeptNameChain(deptNameChain);
            setDeptName(worker);
            LambdaUpdateWrapper<TbOfferWorker> updateWrapper = new UpdateWrapper<TbOfferWorker>().lambda();
            if (StringUtils.isNotBlank(personnelRangeCode)) {
                updateWrapper.set(TbOfferWorker::getPersonnelRange, personnelRange)
                        .set(TbOfferWorker::getPersonnelRangeCode, personnelRangeCode)
                        .set(TbOfferWorker::getSubPersonnelRange, subPersonnelRange)
                        .set(TbOfferWorker::getSubPersonnelRangeCode, subPersonnelRangeCode)
                        .set(TbOfferWorker::getWorkCity, workCity)
                        .set(TbOfferWorker::getOuterCity, outerCity);
            } else {
                updateWrapper.set(TbOfferWorker::getDeptNameChain, deptNameChain)
                        .set(TbOfferWorker::getPostName, postName)
                        .set(TbOfferWorker::getPostId, postId)
                        .set(TbOfferWorker::getDept1name, worker.getDept1name())
                        .set(TbOfferWorker::getDept2name, worker.getDept2name())
                        .set(TbOfferWorker::getDept3name, worker.getDept3name())
                        .set(TbOfferWorker::getDept4name, worker.getDept4name());
            }
            updateWrapper.eq(TbOfferWorker::getWorkerId, workerId);
            update(updateWrapper);
            updateOfferWorkerToSap(workerId);
        }
        approvalRecordService.saveRecord(flowId, BusiEnumDefine.FLOW_STATUS_BP, commService.getLoginUserId(),
                commService.getLoginUserNameAndId(), "修改offer信息", 1);
        return "SUCCESS";
    }

    public void setDeptName(TbOfferWorker worker) {
        String nameChain = worker.getDeptNameChain();
        if (StringUtils.isBlank(nameChain)) {
            return;
        }
        String[] deptNameArr = nameChain.split("/");
        if (deptNameArr.length > 0) {
            worker.setDept1name(deptNameArr[0]);
        }
        if (deptNameArr.length > 1) {
            worker.setDept2name(deptNameArr[1]);
        }
        if (deptNameArr.length > 2) {
            worker.setDept3name(deptNameArr[2]);
        }
        if (deptNameArr.length > 3) {
            worker.setDept4name(deptNameArr[3]);
        }
    }

    public void updateOfferWorkerToSap(String workerId) {
        TbOfferWorker newOfferWorker = getById(workerId);
        BeiSenBuildDTO buildDTO = new BeiSenBuildDTO();
        OfferWorker parseObject = JSONObject.parseObject(JSON.toJSONString(newOfferWorker), OfferWorker.class);
        parseObject.setPostInfo(newOfferWorker.getPostId());
        buildDTO.setTbOfferWorker(parseObject);
        beiSenService.callSapForUpdatePreWorker(buildDTO);
    }

    @Override
    public JSONObject getOfferAdjust(String workerId, String recordId) {
        return iTbOfferModifyService.getOfferModifyInfo(workerId, recordId);
    }

    /**
     * 员工填写有问题发送反馈邮件
     * @param content
     */
    public void sendHelpMsgWhenSubmit(String content, String type) {
        String userId = CommonUtil.getActivUser().getUserId();
        TbOfferWorker offerWorker = iTbOfferWorkerService.getById(userId);
        StringBuilder mailContent = new StringBuilder();
        String part = "学习经历";
        if (BusiEnumDefine.EDIT_WORK.equals(type)) {
            part = "工作经历";
        }
        mailContent.append("您好<br>预备员工 ")
                .append(offerWorker.getWorkerName()).append("/").append(offerWorker.getWorkerId())
                .append(" 因").append(part).append("问题无法提交，具体问题如下：“").append(content).append("”<br>请评估后予以反馈").append(emailTail())
                .append("<br>员工联系电话：").append(offerWorker.getPhoneNo()).append(" 邮箱：").append(offerWorker.getEmail());
        SdNoticeRecord noticeRecord = new SdNoticeRecord();
        noticeRecord.setNoticeId(IdWorker.nextId() + "");
        noticeRecord.setFlowId("-1");
        noticeRecord.setApplyUserId(userId);
        noticeRecord.setNoticeType(BusiEnumDefine.NOTICE_TYPE_EMAIL);
        noticeRecord.setNoticeTitle("预备员工" + offerWorker.getWorkerName() + "提交学历/工作经历信息问题反馈");
        noticeRecord.setTargetEmail(feedbackMail);
        noticeRecord.setNoticeContent(mailContent.toString());
        noticeRecord.setCreateTime(new Date());
        asyncSendMessage.sendMessage(Collections.singletonList(noticeRecord));
    }

    public String emailTail() {
        return "<a href=\"https://newemployee.h3c.com\" target=\"_blank\">点此进入</a>";
    }

    /**
     * 能否编辑北森数据
     * @param workerId
     * @param auth
     */
    public void updateEditBeisenAuth(String workerId, String auth) {
        TbOfferWorker offerWorker = getById(workerId);
        if (offerWorker != null) {
            if (!(offerWorker.getWorkerStatus().equals(OfferWorkerStatusEnum.待填写入职资料) || offerWorker.getWorkerStatus().equals(OfferWorkerStatusEnum.待补充资料))) {
                throw new AppBusinessException("员工不在待填写状态，无需修改");
            }
            String oriAuth = offerWorker.getEditBeisenAuth();
            LambdaUpdateWrapper<TbOfferWorker> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(TbOfferWorker::getWorkerId, workerId)
                    .set(TbOfferWorker::getEditBeisenAuth, auth);
            iTbOfferWorkerService.update(updateWrapper);
            String editPart = "";
            if (BusiEnumDefine.EDIT_NONE.equals(oriAuth)) {
                if (BusiEnumDefine.EDIT_STUDY.equals(auth)) {
                    editPart = "学习经历";
                } else {
                    editPart = "工作经历";
                }
            }
            if (BusiEnumDefine.EDIT_BOTH.equals(auth)) {
                editPart = "学习经历和工作经历";
            }
            if (!BusiEnumDefine.EDIT_BOTH.equals(oriAuth) && !BusiEnumDefine.EDIT_NONE.equals(auth) && !StringUtils.isEmpty(offerWorker.getPhoneNo())) {
                SdNoticeRecord msg = new SdNoticeRecord();
                msg.setNoticeId(IdWorker.nextId() + "");
                msg.setFlowId("-1");
                msg.setNoticeType(BusiEnumDefine.NOTICE_TYPE_SMS);
                msg.setApplyUserId(CommonUtil.getActivUser().getUserId());
                msg.setTargetName(offerWorker.getWorkerName());
                msg.setTargetPhone(offerWorker.getPhoneNo());
                msg.setNoticeContent("您好，经评估，您可登录H3C新员工入职平台https://rne.h3c.com修改您的"+editPart+"并点击提交，谢谢。");
                msg.setCreateTime(new Date());
                asyncSendMessage.sendMessage(Collections.singletonList(msg));
            }
        }
    }

    /**
     * 您好，您部门的员工【部门、姓名】【联系方式（手机号）】（如有多人，请合并），预计于今日XX年XX月XX日（星期X）入职报道。详细信息可点击链接进入系统查看（如有多人，请合并）
     * 发送时间：于入职前一天（按工作日历看）定点发送（9点）
     * 定时发送第二天入职人员名单
     */
    public void mailToLeaderBeforeJoin() {
        XxlJobLogger.log("发送第二天入职人员名单邮件任务启动");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        Date time = new Date();
        calendar.setTime(time);
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        String format = sdf.format(calendar.getTime());
        List<TbOfferWorker> list = lambdaQuery().eq(TbOfferWorker::getPlanReportDate, format).list();
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        XxlJobLogger.log("人员数量" + list.size());
        Map<String, StringBuilder> leaderMap = new HashMap<>();
        for (TbOfferWorker offerWorker : list) {
            String directManager = offerWorker.getDirectManager();
            String deptNameChain = offerWorker.getDeptNameChain();
            String targetId = "";
            if (!StringUtils.isEmpty(directManager)) {
                SdAllWorker leader = commService.getAllWorkerDoFromLocalCache(directManager.split("/")[1]);
                if (leader != null) {
                    targetId = leader.getWorkerId();
                }
            } else if (!StringUtils.isEmpty(deptNameChain)) {
                SdDept dept = iSdDeptService.getDeptByNameChainNoException(deptNameChain);
                if (dept != null) {
                    String leaderId = dept.getDeptManagerId();
                    if (!StringUtils.isEmpty(leaderId)) {
                        SdAllWorker leader = commService.getAllWorkerDoFromLocalCache(leaderId.split(",")[0]);
                        if (leader != null) {
                            targetId = leader.getWorkerId();
                        }
                    }
                }
            }
            if (!StringUtils.isEmpty(targetId)) {
                StringBuilder contentSb = leaderMap.get(targetId);
                if (contentSb == null) {
                    StringBuilder sb = new StringBuilder();
                    sb.append("您好，您部门的员工<br>")
                            .append(offerWorker.getDeptNameChain())
                            .append("  ")
                            .append("<span style=\"font-weight: bold;\">")
                            .append(offerWorker.getWorkerName())
                            .append("</span>")
                            .append("(手机号:").append(offerWorker.getPhoneNo()).append(")")
                            .append("<br>");
                    leaderMap.put(targetId, sb);
                } else {
                    contentSb.append(offerWorker.getDeptNameChain())
                            .append("  ")
                            .append("<span style=\"font-weight: bold;\">")
                            .append(offerWorker.getWorkerName())
                            .append("</span>")
                            .append("(手机号:").append(offerWorker.getPhoneNo()).append(")")
                            .append("<br>");
                }
            }
        }
        List<SdNoticeRecord> leaderMails = new ArrayList<>();
        leaderMap.forEach((k, v) -> {
            SdAllWorker leader = commService.getAllWorkerDoFromLocalCache(k);
            if (leader != null) {
                XxlJobLogger.log("接收邮件主管工号" + k);
                v.append("预计于").append(format).append("(").append(com.h3c.nem.utils.DateUtil.dateToWeek(calendar.getTime())).append(")入职报到。详细信息可<a href=\"https://newemployee.h3c.com/prepareBPManage/employeesList\" target=\"_blank\">点击链接</a>进入系统查看。");
                SdNoticeRecord mail = new SdNoticeRecord();
                mail.setNoticeId(IdWorker.nextId() + "");
                mail.setFlowId("-1");
                mail.setApplyUserId("system");
                mail.setNoticeType(BusiEnumDefine.NOTICE_TYPE_EMAIL);
                mail.setTargetId(k);
                mail.setTargetName(leader.getWorkerName());
                mail.setTargetEmail(leader.getEmail());
                mail.setNoticeTitle("您部门有员工将于明日入职");
                mail.setNoticeContent(v.toString());
                mail.setCreateTime(time);
                leaderMails.add(mail);
            }
        });

        if (!CollectionUtils.isEmpty(leaderMails)) {
            asyncSendMessage.sendMessage(leaderMails);
        }
    }

    /**
     * "有未报到人员，给主管推送
     * 您好，您部门的员工【部门、姓名】【联系方式（手机号）】（如有多人，请合并），今日未完成报到。
     * 详细信息可点击链接进入系统查看（如有多人，请合并）
     * 发送时间：入职当天定点发送（17:00点）
     * 未报到状态认定：未生成工号（17:00点）"
     */
    public void mailToLeaderWhenJoin() {
        XxlJobLogger.log("发送当天未完成报到人员邮件任务启动");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date time = new Date();
        String format = sdf.format(time);
        List<TbOfferWorker> list = lambdaQuery().eq(TbOfferWorker::getPlanReportDate, format).isNull(TbOfferWorker::getRegularWorkerId).list();
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        XxlJobLogger.log("人员数量" + list.size());
        Map<String, StringBuilder> leaderMap = new HashMap<>();
        for (TbOfferWorker offerWorker : list) {
            String directManager = offerWorker.getDirectManager();
            String deptNameChain = offerWorker.getDeptNameChain();
            String targetId = "";
            if (!StringUtils.isEmpty(directManager)) {
                SdAllWorker leader = commService.getAllWorkerDoFromLocalCache(directManager.split("/")[1]);
                if (leader != null) {
                    targetId = leader.getWorkerId();
                }
            } else if (!StringUtils.isEmpty(deptNameChain)) {
                SdDept dept = iSdDeptService.getDeptByNameChainNoException(deptNameChain);
                if (dept != null) {
                    String leaderId = dept.getDeptManagerId();
                    if (!StringUtils.isEmpty(leaderId)) {
                        SdAllWorker leader = commService.getAllWorkerDoFromLocalCache(leaderId.split(",")[0]);
                        if (leader != null) {
                            targetId = leader.getWorkerId();
                        }
                    }
                }
            }
            if (!StringUtils.isEmpty(targetId)) {
                StringBuilder contentSb = leaderMap.get(targetId);
                if (contentSb == null) {
                    StringBuilder sb = new StringBuilder();
                    sb.append("您好，您部门的员工<br>")
                            .append(offerWorker.getDeptNameChain())
                            .append("  ")
                            .append("<span style=\"font-weight: bold;\">")
                            .append(offerWorker.getWorkerName())
                            .append("</span>")
                            .append("(手机号:").append(offerWorker.getPhoneNo()).append(")")
                            .append("<br>");
                    leaderMap.put(targetId, sb);
                } else {
                    contentSb.append(offerWorker.getDeptNameChain())
                            .append("  ")
                            .append("<span style=\"font-weight: bold;\">")
                            .append(offerWorker.getWorkerName())
                            .append("</span>")
                            .append("(手机号:").append(offerWorker.getPhoneNo()).append(")")
                            .append("<br>");
                }
            }
        }
        List<SdNoticeRecord> leaderMails = new ArrayList<>();
        leaderMap.forEach((k, v) -> {
            SdAllWorker leader = commService.getAllWorkerDoFromLocalCache(k);
            if (leader != null) {
                XxlJobLogger.log("接收邮件主管工号" + k);
                v.append("今日未完成报到。详细信息可<a href=\"https://newemployee.h3c.com/prepareBPManage/employeesList\" target=\"_blank\">点击链接</a>进入系统查看。");
                SdNoticeRecord mail = new SdNoticeRecord();
                mail.setNoticeId(IdWorker.nextId() + "");
                mail.setFlowId("-1");
                mail.setApplyUserId("system");
                mail.setNoticeType(BusiEnumDefine.NOTICE_TYPE_EMAIL);
                mail.setTargetId(k);
                mail.setTargetName(leader.getWorkerName());
                mail.setTargetEmail(leader.getEmail());
                mail.setNoticeTitle("您部门有员工今日未完成报到");
                mail.setNoticeContent(v.toString());
                mail.setCreateTime(time);
                leaderMails.add(mail);
            }
        });

        if (!CollectionUtils.isEmpty(leaderMails)) {
            asyncSendMessage.sendMessage(leaderMails);
        }
    }

}

